Лучший шаблон проектирования для изоляции методов дочерних объектов, содержащихся в массиве родительских объектов - PullRequest
2 голосов
/ 08 сентября 2010

Я пытаюсь найти лучший шаблон проектирования, чтобы изолировать дочерний объект от слишком многого знания о родительском объекте, в котором он содержится.

Например, с таким родительским классом, как этот ...

class Airplane {
  var seats:Array
  ...

  function removeSeat(seat:Seat) {
    // find seat object in seats array and remove it
  }
}

дочерний класс ...

class Seat {
  var rowNumber:int
  ...
}

Если я работаю в контексте объекта Seat и хочу удалить себя из родительского объекта Airplane, что это такое?лучший способ отделить Seat от знания того, где он находится в массиве Airplane.seats?

Я знаю, что могу передать родительский объект Airplane в конструктор Seat, а затем вызвать метод removeSeat на Airplane для удаленияэто место, но я хочу, чтобы сиденье знало как можно меньше о самолете.Есть идеи?

Ответы [ 3 ]

4 голосов
/ 08 сентября 2010

Вы можете использовать шаблон обработчика событий - по сути, самолет передает обратный вызов removeMe в конструкцию Seat. Затем Seat выполняет этот обратный вызов, когда он хочет быть удаленным. Место не знает, кто прошел обратный вызов - ему просто нужно знать сигнатуру обратного вызова, в этом примере первый параметр является ссылкой на объект Seat.

например. в псевдокоде

class Airplane {
   // will be passed in as callback
  function removeSeat(seat) {
    array.remove(seat);
  }
  ..
  var seat = new Seat();
  seat.removeCallback = removeSeat;
  ..
 }

class Seat() {
    removeCallback = null;
    ...
    ...
    // when we want to remove the seat, run the callback if set
    if (removeCallback !== null) { 
      removeCallback(this);
    }
 }
2 голосов
/ 08 сентября 2010

Попробуйте реализовать вариант шаблона посетителя.

interface SeatContainer {

    function removeSeat(seat:Seat);

}

Тогда ваш самолет реализует интерфейс

class Airplane implements SeatContainer {
  var seats:Array
  ...

  function removeSeat(seat:Seat) {
    // find seat object in seats array and remove it
  }
}

И ваше место содержит ссылку на интерфейс

class Seat {
  var container:Container
  ...
  function removeMyself() {
     container.removeSeat(this);
  }
}

Таким образом, объект Seat игнорирует, в каком виде находится контейнер, будучи изолирован от фактической реализации SeatContainer: это может быть автомобиль, кинотеатр, лодка или любая другая реализация интерфейса SeatContainer.

0 голосов
/ 08 сентября 2010

Чтобы сохранить это разделение, контекст, в котором вы получаете доступ к местам, должен также знать, к какому самолету они принадлежат.Пример:

class AirplaneService {
   public function removeEmptySeats(Airplane airplane) {
      foreach seat in airplane {
         if seat is empty {
            airplane.removeSeat(seat);
         }
      }
   }

   public function removeRowSeats(Airplane airplane, int rowNumber) {
      foreach seat in airplane {
         if seat.getRowNumber() == rowNumber {
            airplane.removeSeat(seat);
         }
      }
   }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...