c++ 模板之 抽象工廠
完成程式碼 見
http://download.csdn.net/detail/zhuyingqingfen/8457091
1. 設計模式中抽象工廠的泛型 實現
2. c++ 自動生成模板程式碼 的例子 具體實現見:c++ 泛型程式設計 之 自動生成程式碼
////////////////////////////////////////////////////////////////////////////////
// The Loki Library
// Copyright (c) 2001 by Andrei Alexandrescu
// This code accompanies the book:
// Alexandrescu, Andrei. "Modern C++ Design: Generic Programming and Design
// Patterns Applied". Copyright (c) 2001. Addison-Wesley.
// Permission to use, copy, modify, distribute and sell this software for any
// purpose is hereby granted without fee, provided that the above copyright
// notice appear in all copies and that both that copyright notice and this
// permission notice appear in supporting documentation.
// The author or Addison-Wesley Longman make no representations about the
// suitability of this software for any purpose. It is provided "as is"
// without express or implied warranty.
////////////////////////////////////////////////////////////////////////////////
#ifndef LOKI_ABSTRACTFACTORY_INC_
#define LOKI_ABSTRACTFACTORY_INC_
// $Id: AbstractFactory.h 771 2006-10-27 18:05:03Z clitte_bbt $
#include "HierarchyGenerators.h"
#include "typelists.h"
#include <cassert>
#include <iostream>
namespace Loki
{
////////////////////////////////////////////////////////////////////////////////
//Type2Type<T> 用於消除歧義,因為同一個繼承體會有多個AbstractFactoryUnit的具現體
//如:AbstractFactoryUnit<A> ,AbstractFactoryUnit<B>等
//DoCreate這個函式返回的並不是一個常型別,因為T為可變的
//在c++中,你可以"返回型別為Pointer to Derived class "的函式改寫(overide)為“返回
// pointer to base class"的函式。這個就是”協變式返回型別(covariant return types)
/*
class A{
public:
virtual A * ff() = 0;
};
class B:public A{
public:
B * ff(){return this;}
};
使用:
B b;
*/
////////////////////////////////////////////////////////////////////////////////
template <class T>
class AbstractFactoryUnit
{
public:
virtual T* DoCreate(Type2Type<T>) = 0;
virtual ~AbstractFactoryUnit() {}
};
////////////////////////////////////////////////////////////////////////////////
// class template AbstractFactory
// Defines an Abstract Factory interface starting from a typelist
////////////////////////////////////////////////////////////////////////////////
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>());
}
};
////////////////////////////////////////////////////////////////////////////////
// class template OpNewFactoryUnit
// Creates an object by invoking the new operator
////////////////////////////////////////////////////////////////////////////////
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>)
{//AbstractProduct抽象產品,ConcreteProduct具體產品,同Soldier和SillySoldier的關係
std::cout<<"基類:"<<typeid(Base).name()<<std::endl;
std::cout<<"基類產品:"<<typeid(BaseProductList).name()<<std::endl;
std::cout<<"抽象名稱:"<<typeid(AbstractProduct).name()<<std::endl;
std::cout<<"具體實現:"<<typeid(ConcreteProduct).name()<<std::endl;
std::cout<<"剩餘的:"<<typeid(ProductList).name()<<std::endl;
return new ConcreteProduct;
}
};
////////////////////////////////////////////////////////////////////////////////
// AbstractFact:提供的是“欲實現的abstract factory介面”,並隱式提供了一組產品(products)
// Creator: 是個Policy,規定如何實際生成物件。
// TList: 提供了“這個factory所要生成的concrete classes”的集合。
// 這個typelist中的每一個具象型別都有一個abstractFactory的typelist中
// 具有相同索引的抽象型別。
// 使用Reverse的原因:
/*
OpNewFactoryUnit 生成過載函式DoCreate是從上到下的順序生成的(體現在ProductList上,因為繼承類都是從父類
找到Head,然後再把Tail傳遞給下面的類。如果BaseProductList是Soldier, Monster, SuperMonster,那麼
子類的AbstractProduct是Soldier,ProductList是Monster, SuperMonster,再往下繼承AbstractProduct是Monster
ProductList是SuperMonster,而ConcreteFactory 把引數TList 傳遞給OpNewFactoryUnit中的ConcreteProduct引數
是從下到上的,如果是ConcreteFactory中的TList是SillySoldier, SillyMonster, SillySuperMonster,那麼
ConcreteFactory的繼承關係樹中從下到上OpNewFactoryUnit的ConcreteProduct依次是SillySoldier,SillyMonster,SillySuperMonster
這樣正好和 DoCreate(Type2Type<AbstractProduct>)中的AbstractProduct的順序相反,所以需要Reverse一下
當然也可以修改OpNewFactoryUnit 而不翻轉ConcreteFactory中的TList 修改成如下:
typedef typename Base::ProductList BaseProductList;
protected:
typedef typename Reverse<typename Reverse<BaseProductList>::Result::Tail>::Result ProductList;
public:
typedef typename Reverse<BaseProductList>::Result::Head AbstractProduct;
不過這種設計不太好,因為每個Creator都要處理這種翻轉情況,不如在ConcreteFactory類中一下徹底解決問題好。
*/
////////////////////////////////////////////////////////////////////////////////
template
<
class AbstractFact,
template <class, class> class Creator = OpNewFactoryUnit,
class TList = typename AbstractFact::ProductList
>
class ConcreteFactory
: public GenLinearHierarchy<typename Reverse<TList>::Result, Creator, AbstractFact>
{
public:
typedef typename AbstractFact::ProductList ProductList;
typedef TList ConcreteProductList;
};
} // namespace Loki
#endif // end file guardian
class Soldier { public: virtual ~Soldier() {} };
class Monster { public: virtual ~Monster() {} };
class SuperMonster { public: virtual ~SuperMonster() {} };
class SillySoldier : public Soldier {};
class SillyMonster : public Monster {};
class SillySuperMonster : public SuperMonster {};
class BadSoldier : public Soldier {};
class BadMonster : public Monster {};
class BadSuperMonster : public SuperMonster {};
void abstractfactory_test()
{
using namespace Loki;
typedef AbstractFactory<TYPELIST_3(Soldier, Monster, SuperMonster)> AbstractEnemyFactory;
typedef ConcreteFactory<AbstractEnemyFactory, OpNewFactoryUnit,
TYPELIST_3(SillySoldier, SillyMonster, SillySuperMonster)> EasyLevelEnemyFactory;
typedef ConcreteFactory<AbstractEnemyFactory, OpNewFactoryUnit,
TYPELIST_3(BadSoldier, BadMonster, BadSuperMonster)> HardLevelEnemyFactory;
std::auto_ptr<AbstractEnemyFactory> easyFactory(new EasyLevelEnemyFactory);
std::auto_ptr<AbstractEnemyFactory> hardFactory(new HardLevelEnemyFactory);
//1
Monster *s;
s = easyFactory->Create<Monster>();
delete s;
//2
AbstractFactoryUnit<Soldier> & soldier_V = *easyFactory;
AbstractFactoryUnit<Monster> & monster_V = *easyFactory;
AbstractFactoryUnit<SuperMonster> & superMonster_V = *easyFactory;
}
下圖 為 兩個類 的繼承關係圖
相關文章
- 工廠三兄弟之抽象工廠模式(二)抽象模式
- 工廠三兄弟之抽象工廠模式(一)抽象模式
- 【設計模式之抽象工廠】設計模式抽象
- 設計模式之工廠方法模式|抽象工廠模式設計模式抽象
- Java設計模式之簡單工廠、工廠方法和抽象工廠Java設計模式抽象
- 設計模式之-抽象工廠-AbstractFactory設計模式抽象
- 建立型:工廠模式-工廠方法、抽象工廠模式抽象
- 簡單工廠,工廠方法和抽象工廠抽象
- 抽象工廠模式抽象模式
- Java 設計模式之工廠方法模式與抽象工廠模式Java設計模式抽象
- 簡單工廠 VS 工廠方法 VS 抽象工廠抽象
- 簡單工廠、工廠方法和抽象工廠模式抽象模式
- golang設計模式之抽象工廠模式Golang設計模式抽象
- 設計模式系列之「抽象工廠模式」設計模式抽象
- 23種設計模式之抽象工廠設計模式抽象
- 一起學模式之抽象工廠模式抽象
- 設計模式之工廠模式!深入解析簡單工廠模式,工廠方法模式和抽象工廠模式設計模式抽象
- 工廠模式 抽象模式模式抽象
- 建立型-抽象工廠抽象
- java 抽象工廠模式Java抽象模式
- 06: 抽象工廠模式抽象模式
- 簡單工廠模式和抽象工廠模式模式抽象
- 簡單工廠模式、工廠模式、抽象工廠模式比較模式抽象
- Java常用設計模式之抽象工廠模式Java設計模式抽象
- 23種設計模式之抽象工廠模式設計模式抽象
- 簡單工廠和抽象工廠的區別抽象
- 抽象工廠模式-與-工廠方法模式區別抽象模式
- 綜合使用抽象工廠、工廠方法的應用抽象
- 設計模式-簡單工廠、工廠方法模式、抽象工廠模式設計模式抽象
- 【Python】抽象工廠模式Python抽象模式
- 設計模式----抽象工廠設計模式抽象
- 設計模式 – 抽象工廠設計模式抽象
- 建立型模式:抽象工廠模式抽象
- 設計模式 - 抽象工廠設計模式抽象
- 抽象工廠模式(C#)抽象模式C#
- 這是抽象工廠麼?抽象
- 04_抽象工廠模式抽象模式
- Java抽象工廠模式案例Java抽象模式