1. 程式人生 > 其它 >範型抽象工廠模式

範型抽象工廠模式

本節介紹範型程式設計中的抽象工廠模式。

一、AbstractFactory的定義

template< class TList,  template <class> class Unit = AbstractFactoryUnit>
class AbstractFactory : public GenScatterHierarchy<TList, Unit>{
public:   
typedef TList ProductList;   
template <class T> T* Create()  {      
      Unit <T>& unit = *this;      
      return unit.DoCreate(Type2Type<T>());  
}
};

其中的Type2Type定義如下

template <typename T>
struct Type2Type{   
    typedef T OriginalType;
};

其中的AbstractFactoryUnit定義如下

template <class T>class AbstractFactoryUnit
{
public:   
  virtual T* DoCreate(Type2Type<T>) = 0;  
  virtual ~AbstractFactoryUnit() {}
};

其中GenScatterHierarchy的定義如下

template <class TList, template <class> class Unit> class GenScatterHierarchy;

// GenScatterHierarchy specialization: Typelist to Unit
template <class Head, class Tail, template <class> class Unit>
class GenScatterHierarchy<Typelist<Head, Tail>, Unit> : public GenScatterHierarchy<Head, Unit> , public GenScatterHierarchy<Tail, Unit>{
public:   
    typedef typename Typelist<Head, Tail> TList;   
    typedef typename GenScatterHierarchy<Head, Unit> LeftBase;   
    typedef typename GenScatterHierarchy<Tail, Unit> RightBase;
};

// Pass an atomic type (non-typelist) to Unit
template <class AtomicType, template <class> class Unit>
class GenScatterHierarchy : public Unit<AtomicType>{
    typedef typename Unit<AtomicType> LeftBase;
};

// Do nothing for NullType
template <template <class> class Unit>
class GenScatterHierarchy<NullType, Unit>{
};

其中Typelist定義如下

template <class T, class U>
struct Typelist{   
typedef T Head;   
typedef U Tail;
};

#define TYPELIST_1(T1) Typelist<T1, NullType>
#define TYPELIST_2(T1, T2) Typelist<T1, TYPELIST_1(T2) >
#define TYPELIST_3(T1, T2, T3) Typelist<T1, TYPELIST_2(T2, T3) >
#define TYPELIST_4(T1, T2, T3, T4) \   
Typelist<T1, TYPELIST_3(T2, T3, T4) >.
..
#define TYPELIST_50(...) ...

二、AbstractFactory的實現

使用ConcreteFactory去具體實現一個抽象工廠

ConcreteFactory的定義如下

template< class AbstractFact,  template <class, class> class Creator = OpNewFactoryUnit,  class TList>
class ConcreteFactory   : public GenLinearHierarchy< typename TL::Reverse<TList>::Result, Creator, AbstractFact>{
public:   
    typedef typename AbstractFact::ProductList ProductList;   
    typedef TList ConcreteProductList;
};

其中OpNewFactoryUnit的定義如下

template <class ConcreteProduct, class Base>class OpNewFactoryUnit : public Base{   
typedef typename Base::ProductList BaseProductList;
protected:   
typedef typename BaseProductList::Tail ProductList;
public:   
typedef typename BaseProductList::Head AbstractProduct;
ConcreteProduct* DoCreate(Type2Type<AbstractProduct>)   {      
    return new ConcreteProduct;   
}
};

其中GenLinearHierarchy的定義如下

template< class TList, template <class AtomicType, class Base> class Unit,   class Root = EmptyType>
class GenLinearHierarchy; 

template<   class T1,   class T2,   template <class, class> class Unit,   class Root>
class GenLinearHierarchy<Typelist<T1, T2>, Unit, Root>   : public Unit< T1, GenLinearHierarchy<T2, Unit, Root> >{
};

template<   class T,   template <class, class> class Unit,   class Root>
class GenLinearHierarchy<TYPELIST_1(T), Unit, Root>   : public Unit<T, Root>{

};

TL::Reverse::ResultTList進行了翻轉,顛倒了TList中各type的順序

三、實際使用

實際使用時,程式碼如下

typedef ConcreteFactory<
     AbstractEnemyFactory,  // the abstract factory to implement
     OpNewFactoryUnit,  //policy for creating objects,for example using new
     TYPELIST_3(SillySoldier, SillyMonster, SillySuperMonster) //concrete classes factory creates 
>EasyLevelEnemyFactory;


// Application code
typedef AbstractFactory<TYPELIST_3(Soldier, Monster, SuperMonster) > AbstractEnemyFactory;

AbstractEnemyFactory* p = new EasyLevelEnemyFactory;

Monster* pOgre=p->Create<Monster>();

其中AbstractFactory經由TYPELIST_3(Soldier, Monster, SuperMonster)生成的繼承體系如下

參考資料

  1. <<Modern C++ design>> Andrei Alexandrescu