我正在试图找出最好的设计模式来隔离子对象,使其不必过多地了解它所包含的父对象。
例如,对于像这样的父类......
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,但我想知道如果可能的话,座位知道飞机很少。有什么想法吗?
答案 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);
}
}
}
}