问题
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 Ship
s, 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