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

第九章 抽象工厂

作者: 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
    
    

    相关文章

      网友评论

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

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