c++ 模板之 抽象工廠

Sunday發表於2015-02-25


完成程式碼 見 

 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;
 
}


下圖 為 兩個類 的繼承關係圖






相關文章