Loki 库提供了用于构建 AbstractFactory 模式的预定义接口。我特别对基于原型的抽象工厂感兴趣。
假设我们有一个具有抽象实体的游戏应用程序:
class Soldier{ };
class Monster{ };
class SuperMonster{ };
和具体实体:
class EasySoldire : public Soldier{ };
class EasyMoster : public Monster{ };
class EasySuperMonster : public SuperMonster{ };
等等
Medium
和Hard
。
现在我想创建基于原型的简易工厂。
这是它在 Loki 中的实现方式(Alexandrescu 的现代 C++ 设计):
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_;
};
所以 ConcreteFactory 看起来像:
typedef AbstractFactory
<
TYPELIST_3(Soldier, Monster, SuperMonster)
>
AbstractEnemyFactory;
typedef ConcreteFactory
<
AbstractEnemyFactory,
PrototypeFactoryUnit
>
EnemyFactory;
现在我的问题是我们如何从具体工厂定义
Easy
级别工厂?
我建议:
EnemyFactory easyFactory;
easyFactory.SetPrototype<EasySoldier>(new EasySoldier);
easyFactory.SetPrototype<EasyMonster>(new EasyMonster);
easyFactory.SetPrototype<EasySuperMonster>(new EasySuperMonster);
Soldier* pSoldier = easyFactory.Create<Soldier>();
Monster* pMonster = easyFactory.Create<Monster>();
SuperMonster* pSuperMonster = easyFactory.Create<SuperMonster>();
注意,Loki 的原型工厂要求类层次结构的所有元素都定义一个 Clone 方法,即:
class Enemy
{
virtual Enemy* Clone() const = 0;
virtual ~Enemy() {}
};
class Soldier : public Enemy
{
public:
virtual Soldier* Clone() const override = 0;
virtual ~Soldier() {}
};
class EasySoldier : public Soldier
{
public:
EasySoldier* Clone() const override { return new EasySoldier(*this); };
};
等等。