首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> C++ >> 關於C++

C++ 模板之抽象工廠:Loki 庫風格泛型實現

     編輯:關於C++

設計目標

使用模板元編程自動生成抽象工廠接口及其具體實現,支持:

  • 任意產品類型列表 (TypeList)。
  • 可插拔的創建策略 (Creator Policy,如 `new`、原型複製、單例等)。
  • 類型安全的 `Create()` 接口。

核心組件

1. AbstractFactoryUnit

單個產品的抽象創建接口,使用 `Type2Type` 消除重載歧義:

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

2. AbstractFactory (散亂繼承)

繼承 `GenScatterHierarchy`,提供便捷 `Create()`:

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

3. OpNewFactoryUnit (創建策略)

使用 `new` 創建對象,繼承鏈中自動獲取抽象產品類型:

template 
class OpNewFactoryUnit : public Base {
    typedef typename Base::ProductList BaseProductList;
protected:
    typedef typename BaseProductList::Tail ProductList;
public:
    typedef typename BaseProductList::Head AbstractProduct;
    // ConcreteProduct 由具體工廠指定
    ConcreteProduct* DoCreate(Type2Type) {
        return new ConcreteProduct();
    }
};

4. ConcreteFactory (線性繼承 + 類型映射)

將抽象產品列表映射到具體產品列表,線性繼承鏈自動實現所有 `DoCreate`:

template <
    class AbstractFact,
    template class Creator = OpNewFactoryUnit,
    class TList = typename AbstractFact::ProductList
>
class ConcreteFactory 
    : public GenLinearHierarchy<
          typename Reverse::Result, // 反轉順序匹配線性繼承
          Creator,
          AbstractFact
      > {
public:
    typedef typename AbstractFact::ProductList ProductList;
    typedef TList ConcreteProductList;
};

使用示例

// 產品層次
class Soldier { virtual ~Soldier() {} };
class Monster { virtual ~Monster() {} };
class SuperMonster { virtual ~SuperMonster() {} };

class SillySoldier : public Soldier {};
class SillyMonster : public Monster {};
class SillySuperMonster : public SuperMonster {};

// 定義工廠
typedef AbstractFactory AbstractEnemyFactory;
typedef ConcreteFactory EasyFactory;

// 使用
std::auto_ptr factory(new EasyFactory);
Monster* m = factory->Create(); // 返回 SillyMonster*
delete m;

關鍵設計細節

  • `Reverse`:線性繼承從頭構建,需反轉列表使第一個具體類型對應第一個抽象類型。
  • `Type2Type`:空類模板,用於函數參數區分同名不同類型的重載。`DoCreate(Type2Type)` 比 `DoCreate(T*)` 更安全 (不需實例)。
  • 協變返回類型:`DoCreate` 返回 `ConcreteProduct*` 可隱式轉換為 `AbstractProduct*`。

繼承關係圖解

散亂繼承體系 線性繼承體系

總結

此模式展示了 C++ 模板元編程「類型列表驅動類生成」的強大能力,將設計模式 (抽象工廠) 固化為可復用的庫組件,實現「零樣板代碼」的類型安全工廠創建。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved