Composite Pattern Reuse For Different Types

喜欢而已 提交于 2019-12-11 01:55:39

问题


Extending a naval simulation project, I'm looking to add the Composite Pattern so I can have groups of objects. This is what the current hierarchy looks like:

class Sim_object {
};

class Ship : public Sim_object {
};

class Island : public Sim_object {
};

And so far I've come up with:

class Sim_object {
  // holds general sim functions
  get_name()
};

// COMPONENT
class Ship_object : public Sim_object {
  // holds ship functions
  add()
  remove()
  attack()
  move()
};

// COMPOSITE
class Group : public Ship_object {
   // holds list of group ship functions
   add()
   remove()
   attack()
   move()
};

// LEAF
class Ship : public Ship_object {
   // holds ship functions
   attack()
   move()
};

class Island : public Sim_object {
  // holds island functions
};  

I have it working, but it only works for Ships and groups of Ship. I'd like to reuse the Group code (add, remove, display, etc.) so then a concrete Group class (like Island_group) can just inherit from this and use it. I tried changing the design where Ship_group class inherits from a common base class called Group, but I was faced with a diamond program.

Is there any way I can go about reusing my Group control code based on the type?


回答1:


The composite, in order to work with more than one type of Sim_object, should inherit and compose Sim_objects:

class Sim_object { };
class Ship : public Sim_object { };
class Island : public Sim_object { }; 
class Group : public Sim_object { 
  add()
  remove()
}; 

To tailor it to specific types, you could templatize it, and (possibly) derive other groups from it:

template <class T>
class Group : public Sim_object {
  add()
  remove()
};

class Ship_Group : public Group<Ship> {
  attack()
  move()
};

class Island_Group : public Group<Island> { } // possibly unnecessary

Now, to have your Ship_Group substitute Ships, you could create an "interface" (pure-virtual class) for Ship and inherit Ship_Group from it as well. You'd also use your new interface instead of the concrete Ship in client code:

class Ship_Like { // interface
  attack() = 0
  move() = 0
};
class Ship : public Sim_object, public Ship_Like { }; // concrete
class Ship_Group : public Group<Ship>, public Ship_Like { 
  attack()
  move()
}

No worries about diamond-problems there...



来源:https://stackoverflow.com/questions/10112359/composite-pattern-reuse-for-different-types

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!