最佳设计模式,用于隔离父对象数组中包含的子对象方法

时间:2010-09-08 11:13:34

标签: design-patterns oop

我正在试图找出最好的设计模式来隔离子对象,使其不必过多地了解它所包含的父对象。

例如,对于像这样的父类......

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数组中的位置的最佳方法是什么?< / p>

我知道我可以将Airplane父对象传递到Seat的构造函数中,然后调用Airplane上的removeSeat方法来移除该Seat,但我想知道如果可能的话,座位知道飞机很少。有什么想法吗?

3 个答案:

答案 0 :(得分:4)

您可以使用事件处理程序模式 - 基本上飞机将'removeMe'回调传递给构建中的Seat。然后,当要删除时,Seat会执行此回调。座位不知道是谁传入了回调 - 它只需要知道回调的签名,在这个例子中,第一个参数是对Seat对象的引用。

E.g。在伪代码中

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);
    }
 }

答案 1 :(得分:2)

尝试实施访客模式的变体。

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的实际实现隔离:它可以是Car,Cinema,Boat或SeatContainer接口的任何实现。

答案 2 :(得分:0)

为了保持这种分离,你访问座位的环境也应该知道它们属于的飞机。例如:

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);
         }
      }
   }
}