Loki library provides predefined interfaces for building AbstractFactory pattern. Particularly, I'm interested in prototype-based abstract factory.
Assume that we have a game application which has Abstract Entities:
class Soldier{ };
class Monster{ };
class SuperMonster{ };
and Concrete Entites:
class EasySoldire : public Soldier{ };
class EasyMoster : public Monster{ };
class EasySuperMonster : public SuperMonster{ };
And so forth for Medium and Hard.
Now I want to create Prototype-based easy-level factory.
Here is how it's implemented in Loki (Alexandrescu's Moder C++ Design):
template
<
class AbstractFact,
template <class, class> class Creator,
class TList = typename AbstractFact::ProductList
>
class ConcreteFactory;
template <class ConcreteProduct, class Base>
class PrototypeFactoryUnit : public Base
{
typedef typename Base::ProductList BaseProductList;
protected;
typedef typename Base::ProductList TailProductList;
public;
typedef typename Base::ProductList::Head AbstractProduct;
PrototypeFactoryUnit(AbstractProduct* p = 0)
:pPrototype_(p) {}
friend void DoGetPrototype(const PrototypeFactoryUnit& me,
AbstractProduct*& pPrototype)
{
pPrototype = me.pPrototype_;
}
friend void DoSetPrototype(PrototypeFactoryUnit& me,
AbstractProduct* pObj)
{
me.pPrototype_=pObj;
}
template <class U>
void GetPrototype(AbstractProduct*& p)
{
return DoGetPrototype(*this, p);
}
template <class U>
void SetPrototype(U* pObj)
{
DoSetPrototype(*this, pObj);
}
AbstractProduct* DoCreate(Type2Type<AbstractProduct>)
{
assert(pPrototype_);
return pPrototype_->Clone();
}
private:
AbstractProduct* pPrototype_;
};
So the ConcreteFactory will look like:
typedef AbstractFactory
<
TYPELIST_3(Soldier, Monster, SuperMonster)
>
AbstractEnemyFactory;
typedef ConcreteFactory
<
AbstractEnemyFactory,
PrototypeFactoryUnit
>
EnemyFactory;
Now my question is how can we define Easy level factory from that conrete factory?
I suggest:
Be careful, Loki's prototype factory demands all the elements of the class hierarchy to define a Clone method, that is:
and so on.