美文网首页
第九章 抽象工厂

第九章 抽象工厂

作者: szn好色仙人 | 来源:发表于2018-04-29 19:57 被阅读0次
////////////////////////////////////////////////////////////////////////////////
// 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 "Typelist.h"
#include "Sequence.h"
#include "TypeManip.h"
#include "HierarchyGenerators.h"

#include <cassert>

/**
 * \defgroup    FactoriesGroup Factories
 * \defgroup    AbstractFactoryGroup Abstract Factory
 * \ingroup     FactoriesGroup
 * \brief       Implements an abstract object factory.
 */
 
/**
 * \class       AbstractFactory
 * \ingroup     AbstractFactoryGroup
 * \brief       Implements an abstract object factory.
 */

namespace Loki
{

////////////////////////////////////////////////////////////////////////////////
// class template AbstractFactoryUnit
// The building block of an Abstract Factory
////////////////////////////////////////////////////////////////////////////////

    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>)
        {
            return new ConcreteProduct;
        }
    };

////////////////////////////////////////////////////////////////////////////////
// class template PrototypeFactoryUnit
// Creates an object by cloning a prototype
// There is a difference between the implementation herein and the one described
//     in the book: GetPrototype and SetPrototype use the helper friend 
//     functions DoGetPrototype and DoSetPrototype. The friend functions avoid
//     name hiding issues. Plus, GetPrototype takes a reference to pointer
//     instead of returning the pointer by value.
////////////////////////////////////////////////////////////////////////////////

    template <class ConcreteProduct, class Base>
    class PrototypeFactoryUnit : public Base
    {
        typedef typename Base::ProductList BaseProductList;
    
    protected:
        typedef typename BaseProductList::Tail ProductList;

    public:
        typedef typename BaseProductList::Head AbstractProduct;

        PrototypeFactoryUnit(AbstractProduct* p = 0)
            : pPrototype_(p)
        {}

        template <class CP, class Base1>
        friend void DoGetPrototype(const PrototypeFactoryUnit<CP, Base1>& me,
                                   typename Base1::ProductList::Head*& pPrototype);

        template <class CP, class Base1>
        friend void DoSetPrototype(PrototypeFactoryUnit<CP, Base1>& me,
                                   typename Base1::ProductList::Head* pObj);

        template <class U>
        void GetPrototype(U*& p)
        { return DoGetPrototype(*this, p); }
        
        template <class U>
        void SetPrototype(U* pObj)
        { DoSetPrototype(*this, pObj); }
        
        AbstractProduct* DoCreate(Type2Type<AbstractProduct>)
        {
            assert(pPrototype_);
            return pPrototype_->Clone();
        }
        
    private:
        AbstractProduct* pPrototype_;
    };

    template <class CP, class Base>
    inline void DoGetPrototype(const PrototypeFactoryUnit<CP, Base>& me,
                               typename Base::ProductList::Head*& pPrototype)
    { pPrototype = me.pPrototype_; }

    template <class CP, class Base>
    inline void DoSetPrototype(PrototypeFactoryUnit<CP, Base>& me,
                               typename Base::ProductList::Head* pObj)
    { me.pPrototype_ = pObj; }

////////////////////////////////////////////////////////////////////////////////
// class template ConcreteFactory
// Implements an AbstractFactory interface
////////////////////////////////////////////////////////////////////////////////

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

} // namespace Loki


#endif // end file guardian

相关文章

  • 第3章 创建型模式-抽象工厂模式

    ■ 抽象工厂模式的优点 ■ 抽象工厂模式的缺点 ■ 抽象工厂模式的使用场景 ■ 抽象工厂 AbstractFact...

  • 抽象工厂模式(选择产品簇)

    目录 回顾众多工厂模式 抽象工厂模式的理念 抽象工厂模式与工厂方法模式的差异 怎么来实现抽象工厂模式 抽象工厂模式...

  • 【抽象工厂模式】Abstract Factory Design

    抽象工厂模式 抽象工厂模式是**Creational **模式之一 抽象工厂模式和工厂模式很相似,甚至可以说抽象工...

  • 第九章 抽象工厂

  • 工厂模式

    工厂模式细分三种:简单工厂模式、工厂模式、抽象工厂模式。 工厂模式相当于抽象了简单工厂模式的工厂类,而抽象工厂模式...

  • 设计模式(三)——抽象工厂模式

    抽象工厂模式 抽象工厂模式是围绕一个超级工厂创建其他工厂。该超级工厂又称为其他工厂的工厂。在抽象工厂中,接口是负责...

  • 工厂模式

    抽象工厂模式:抽象工厂,具体工厂,抽象产品,具体产品 形容词用接口,名词用抽象类 工厂方法就是只生成一种产品的抽象...

  • 抽象工厂

    iOS设计模式 - 抽象工厂 原理图 说明 抽象工厂相当于在简单工厂基础上将工厂进行了抽象 抽象工厂提供了创建一系...

  • 设计模式(3) 抽象工厂模式

    抽象工厂模式 优化抽象工厂 异步工厂 在学习抽象工厂模式前,先来回顾一下前面的简单工厂和工厂方法模式。简单工厂的职...

  • Android 源码设计模式解析与实战 读书笔记 6 抽象工厂模

    创建型设计模式 —— 抽象工厂模式 1. 抽象工厂模式介绍 抽象工厂模式(Abstract Factory Pat...

网友评论

      本文标题:第九章 抽象工厂

      本文链接:https://www.haomeiwen.com/subject/hglalftx.html