AbstractFactory synopsis:
template
<
class TList,
template <class> class Unit = AbstractFactoryUnit
>
class AbstractFactory;
where TList is the typelist of abstract products that the factory creates, and Unit is the template that defines the interface for each type in TList. For example,
typedef AbstractFactory<TYPELIST_3(Soldier, Monster, SuperMonster>
AbstractEnemyFactory;
defines an abstract factory capable of creating Soldiers, Monsters, and SuperMonsters.
AbstractFactoryUnit<T> defines an interface consisting of a pure virtual function with the signature T* DoCreate(Type2Type<T>). Usually you don't call DoCreate directly; instead, you use AbstractFactory::Create.
AbstractFactory exposes a Create template function. You can instantiate Create with any of the types of the abstract products. For example:
AbstractEnemyFactory *pFactory = ...;
Soldier *pSoldier = pFactory->Create<Soldier>();
For implementing the interface that AbstractFactory defines, Loki provides the ConcreteFactory template. ConcreteFactory's synopsis is
template
<
class AbstractFact,
template <class, class> class FactoryUnit = OpNewFactoryUnit,
class TList = AbstractFact::ProductList
>
class ConcreteFactory;
where AbstractFact is the instantiation of AbstractFactory that is to be implemented, FactoryUnit is the implementation of the FactoryUnit creation policy, and TList is the typelist of concrete products.
The FactoryUnit policy implementation has access to both the abstract product and the concrete product that it must create. Loki defines two Creator policies: OpNewFactoryUnit (Section 9.3) and PrototypeFactoryUnit (Section 9.4). They can also serve as examples for implementing custom implementations of the FactoryUnit policy.
OpNewFactoryUnit uses the new operator for creating objects. If you use OpNewFactoryUnit, you must provide a concrete product typelist as the third parameter to ConcreteFactory. For example:
typedef ConcreteFactory
<
AbstractEnemyFactory,
OpNewFactoryUnit,
TYPELIST_3(SillySoldier, SillyMonster, SillySuperMonster)
>
EasyLevelEnemyFactory;
PrototypeFactoryUnit stores pointers to abstract product types and creates new objects by calling the Clone member function of their respective prototypes. This implies that PrototypeFactoryUnit requires each abstract product T to define a virtual member function Clone that returns a T* and whose semantics is to duplicate the object.
When using PrototypeFactoryUnit with ConcreteFactory, you don't provide the third template argument to ConcreteFactory. For example:
typedef ConcreteFactory
<
AbstractEnemyFactory,
PrototypeFactoryUnit,
>
EnemyFactory;