I\'m facing with the following design problem:
TL;TD need to determine if Hero(class) can use specific object while there\'s many heroes implementations
I have
I have simplified the example by removing everything that isn't necessary and generalized to the concept of Item
. A weapon is a subclass of Item, as is a potion, a wand, a flux capacitor, whatever. The use
method does whatever the Item
does to target
. A weapon will attempt to hit and damage target
. A healing potion will heal target
. A flux capacitor will either send target
back in time or zap the expletive deleted out of them with 1.21 gigawatts.
But everything is seen through the lens of Item
. The invoking classes doesn't know what the item is, does, or what it did to target
. target
doesn't even know what was used on it, they just feel the effects. Nobody knows nothin' about the other objects outside of a simple, generic interface.
class Item
{
public:
enum types
{
whole lot of types go here.
They are fairly broad categories, like knife, sword, two handed sword,
healing potion, wand, etc.
};
types getType()
{
return type;
}
virtual bool use(Entity * target) = 0;
private:
types type;
};
class Hero: public Entity{
public:
Hero(std::set & usable): usableItems(usable)
~Hero();
bool use(Item* item,
Entity * target)
{
// this is the magic. If the item's type is in the list of usable items,
// the item is used on the target. They exact type of item or target
// is not known. Polymorphism will take care of everything from here
if (usableItems.find(item->getType()) != usableItems.end())
{
return item->use(target);
}
return false;
}
private:
std::set & usableItems;
};
The point is the main classes are incredibly stupid. They simply provide a framework for much more detailed objects to do the detailed work. VorpalSword
uses generic methods inherited from Weapon
and Item
to see if it hit target
, not knowing that target
is in fact a HugeRedDragon
instance, and if it hit assigns damage and then does the specific things a VorpalSword
does like checking for lopped off limbs.
And all Hero saw was item->use(target)
.