zoukankan      html  css  js  c++  java
  • C++设计模式工厂方法

    定义
    定义一个用于创建对象的接口,让子类决定实例化哪一个类。工厂方法(Factory Method)使一个类的实例化延迟到其子类。也叫虚构造器(Virtual Constructor
     
    结构
    工厂方法
     
    理解
    1.       Product是工厂方法生产产品的抽象基类。
    2.       Creator是生产产品的工厂对象抽象基类。Creator提供创建虚方法即工厂方法FactoryMeothod()FactoryMeothod()由派生类(ConcreteCreator)具体实现,生产对应的具体产品(ConcreteProduct)。
    3.       ConcreteProduct是继承Product的具体产品。
    4.       ConcreteCreator是生产对应具体产品(ConcreteProduct)的具体工厂。它重新实现继承的工厂方法FactoryMeothod(),生产具体产品。
     
    要点
    1.       工厂方法模式中,工厂和产品的基类和派生类是平行关系。抽象产品(Product)对应层次是抽象工厂(Creator)。在派生类层次,每个具体产品(ConcreteProduct)对应一个具体工厂(ConcreteCreator)。换句话说,每新增一个具体产品,就要新增一个对应的具体工厂
    2.       工厂方法的核心是FactoryMeothod(),每个具体工厂都重新实现该接口,产生具体类对象。
    3.       工厂方法分离客户端和具体类的实现。利用子类(即具体工厂),让子类来决定如何来生产一个具体产品。这样,客户端(即调用者)只需要知道这个类的抽象类型,由子类去和具体产品类打交道。
    4.       工厂基类中的方法AnOperation(),不是工厂方法,只是供具体工厂实现的公共接口(可以说是工厂对产品的使用行为)。但个人认为,工厂方法只是生产产品,公共接口的重点应该是产品,因此在产品基类里增加产品使用的公共接口更加实用。
    5.       工厂方法模式的工厂(Creator)若要全局唯一,可以结合单件(Singleton)模式应用。
    6.       关于简单工厂(也叫静态工厂)。工厂方法强调的是“让子类决定实例化什么样的对象”,因为子类知道它们要使用的特定产品。如果我们将CreatorConcreteCreator的角色合一,并且将工厂方法FactoryMeothod()静态化,那么就退化成了简单工厂模式。
     
    应用
    1.       工厂方法应用场景:
    当一个类不知道它所必须创建的对象的类的时候。
    当一个类希望由它的子类来指定它所创建的对象的时候。
    当类将创建对象的职责委托给多个帮助子类中的某一个,并且你希望将哪一个帮助子类是代理者这一信息局部化的时候。(往往放在抽象产品侧)
    2.       Loki库中对工厂方法有一个比较完美的实现,结合了函数对象(Functor),可制定产品创建方法。可参见:http://loki-lib.sourceforge.net/index.php?n=Pattern.FactoryMethod
    3.       源码中的应用
    COSProduct是产品基类。并且有产品的公共使用接口。
    COSCreator是工厂基类。模式结构中的产品使用行为接口AnOperaion并没有出现在工厂基类接口中,放在了产品侧(Start接口)。
    具体工厂可以通过继承COSCreator实现,有多少个具体工厂,就要有多少个具体工厂类。通过C++模板可以避免创建多个具体工厂(模板类CConcreteCreator)。
     
    源码
    #include <iostream>
    #include <string>
    using namespace std;
     
    ///////////////////产品
    class COSProduct
    {
    public:
        virtual ~COSProduct(){};
        //产品的公共接口。相当于AnOperation
        virtual void Start() = 0;
    };
     
    class CWindowsProduct : public COSProduct
    {
    public:
        virtual void Start()
        {
            cout << "Windows start." << endl;
        }
    };
     
    class CLinuxProduct : public COSProduct
    {
    public:
        virtual void Start()
        {
            cout << "Linux start." << endl;
        }
    };
     
    ///////////////////工厂基类
    class COSCreator
    {
    public:
        ~COSCreator(){};
        //工厂方法。生产产品
        virtual COSProductCreate() = 0;
    };
     
    ///////////////////具体工厂
    class CWindowsCreator : public COSCreator
    {
    public:
        virtual COSProductCreate()
        {
            cout << "Create windows…" << endl;
            return new CWindowsProduct;
        };
    };
    class CLinuxCreator : public COSCreator
    {
    public:
        virtual COSProductCreate()
        {
            cout << "Create linux…" << endl;
            return new CLinuxProduct;
        };
    };
     
    /////另一种具体工厂:使用模板避免创建多个具体工厂子类
    template<typename T>
    class CConcreteCreator : public COSCreator
    {
    public:
        CConcreteCreator(const string strProductType) : m_strProductType(strProductType)
        {};
     
        virtual COSProductCreate()
        {
            cout << "ConcreteCreator. product type: " << m_strProductType << endl;
            return new T;
        };
     
    protected:
        string m_strProductType;
    };
     
     
    int main()
    {
        COSCreatorpCreator = NULL;
        COSProduct *pProduct = NULL;
     
        pCreator = new CWindowsCreator;
        pProduct = pCreator->Create();
        pProduct->Start();
        delete pProduct;
        delete pCreator;
     
        pCreator = new CLinuxCreator;
        pProduct = pCreator->Create();
        pProduct->Start();
        delete pProduct;
        delete pCreator;
     
        //另一种实现具体工厂方式:使用模板避免创建子类
        CConcreteCreator<CWindowsProductwindowsCreator("windows");
        pProduct = windowsCreator.Create();
        pProduct->Start();
        delete pProduct;
     
        CConcreteCreator<CLinuxProductlinuxCreator("linux");
        pProduct = linuxCreator.Create();
        pProduct->Start();
        delete pProduct;
     
        system("pause");
        return 0;
    }
     
    输出:
    Create windows…
    Windows start.
    Create linux…
    Linux start.
    ConcreteCreator. product type: windows
    Windows start.
    ConcreteCreator. product type: linux
    Linux start.
     
  • 相关阅读:
    IE页面后退刷新数据加载问题
    小经验: html中 js脚本运行顺序:思路整理
    jquery 之 $.end() 和 $.siblings()
    AI安防智能化发展至今还存在哪些问题?
    别 荣
    你是魔鬼 荣
    完全版权所有的DataGrid操作类及其用法 荣
    几篇关于.net1.1到.net2.0升级的文章(转载)Microsoft .NET Framework 1.1 和 2.0(测试版)兼容性 荣
    几篇关于.net1.1到.net2.0升级的文章(转载)在VS2005 正确地创建、部署和维护由1.1迁移到ASP.NET 2.0 应用程序注意事项 荣
    关于老实 荣
  • 原文地址:https://www.cnblogs.com/buffer/p/2169287.html
Copyright © 2011-2022 走看看