开发者

Best design pattern to insulate child object methods contained in parent object array

开发者 https://www.devze.com 2023-01-15 12:16 出处:网络
I\'m trying to figure out the best design pattern to insulate a child object from knowing too much about the parent object it is contained in.

I'm trying to figure out the best design pattern to insulate a child object from knowing too much about the parent object it is contained in.

For instance, with a parent class like this...

class Airplane {
  var seats:Array
  ...

  function removeSeat(seat:Seat) {
    // find seat object in seats array and remove it
 开发者_如何学编程 }
}

child class...

class Seat {
  var rowNumber:int
  ...
}

If I'm working in the context of the Seat object and I want to remove myself from my parent Airplane object, what is the best way of separating the Seat from knowing about where it is in the Airplane.seats array?

I know I can pass the Airplane parent object into the constructor of the Seat, then call the removeSeat method on Airplane to remove that Seat, but I want to the Seat knowing as little about the Airplane if possible. Any ideas?


You could use the event handler pattern - essentially the airplane passes a 'removeMe' callback into the Seat on construction. The Seat then executes this callback when it wants to be removed. The seat has no idea who passed in the callback - it just needs to know the signature of the callback, in this example that the first parameter is a reference to a Seat object.

E.g. in pseudo-code

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


Try implementing a variation of the Visitor pattern.

interface SeatContainer {

    function removeSeat(seat:Seat);

}

Then your airplane implements the interface

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

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

And your seat hold a reference to the interface

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

This way, the Seat object ignores what kind of container is in, being isolated of the actual implementation of the SeatContainer: it could be a Car, a Cinema, a Boat, or whatever implementation of SeatContainer interface.


In order to keep this separation, the context where you access seats should also know witch airplane they belong. Ex:

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

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号