• C++设计模式-Factory工厂模式


    Factory
    1、定义创建对象的接口,封装对象的创建
    2、将实际创建工作延迟到子类中,例如,类A中药使用类B,B是抽象父类,但是在类A中不知道具体要实例化哪一个B的子类,但是在类A的子类D中是可以知道的。在A中无法使用 new B***()方法
    3、将创建工作延迟到子类中后,核心工厂类不再负责产品的创建,这样核心类成为一个抽象工厂,只提供工厂子类必须实现的接口,这样的好处是可以不用修改已有的工厂类的情况下增加新的产品(每一种产品,都分别对应相应的工厂子类负责其创建工作)

     

    使用场景:用于一类类(所创建的产品继承共同的产品基类)的创建

    实现方式1:所谓的工厂方法模式,对每一个子类产品都分别对应一个工厂子类,用来创建相应的产品,这样若增加了新的产品,只需相应增加工厂子类即可

    优点:不用修改已有代码,开放封闭原则:对扩展开放,对更改封闭

    代码如下:

      1 //IHuman.h
      2 
      3 #pragma once
      4 class IHuman
      5 {
      6 public:
      7     IHuman(void)
      8     {
      9     }
     10     virtual ~IHuman(void)
     11     {
     12     }
     13     virtual void Laugh() = 0;
     14     virtual void Cry() = 0;
     15     virtual void Talk() = 0;
     16 };
     17 
     18 //YellowHuman.h
     19 
     20 #pragma once
     21 #include "ihuman.h"
     22 class CYellowHuman :
     23     public IHuman
     24 {
     25 public:
     26     CYellowHuman(void);
     27     ~CYellowHuman(void);
     28     void Laugh();
     29     void Cry();
     30     void Talk();
     31 };
     32 
     33 //YellowHuman.cpp
     34 
     35 #include "StdAfx.h"
     36 #include "YellowHuman.h"
     37 #include <iostream>
     38 using std::cout;
     39 using std::endl;
     40 CYellowHuman::CYellowHuman(void)
     41 {
     42 }
     43 CYellowHuman::~CYellowHuman(void)
     44 {
     45 }
     46 void CYellowHuman::Cry()
     47 {
     48     cout << "黄色人种会哭" << endl;
     49 }
     50 void CYellowHuman::Laugh()
     51 {
     52     cout << "黄色人种会大笑,幸福呀!" << endl;
     53 }
     54 void CYellowHuman::Talk()
     55 {
     56     cout << "黄色人种会说话,一般说的都是双字节" << endl;
     57 }
     58 
     59 //WhiteHuman.h
     60 
     61 #pragma once
     62 #include "ihuman.h"
     63 class CWhiteHuman :
     64     public IHuman
     65 {
     66 public:
     67     CWhiteHuman(void);
     68     ~CWhiteHuman(void);
     69     void Laugh();
     70     void Cry();
     71     void Talk();
     72 };
     73 
     74 //WhiteHuman.cpp
     75 
     76 #include "StdAfx.h"
     77 #include "WhiteHuman.h"
     78 #include <iostream>
     79 using std::cout;
     80 using std::endl;
     81 CWhiteHuman::CWhiteHuman(void)
     82 {
     83 }
     84 CWhiteHuman::~CWhiteHuman(void)
     85 {
     86 }
     87 void CWhiteHuman::Cry()
     88 {
     89     cout << "白色人种会哭" << endl;
     90 }
     91 void CWhiteHuman::Laugh()
     92 {
     93     cout << "白色人种会大笑,侵略的笑声" << endl;
     94 }
     95 void CWhiteHuman::Talk()
     96 {
     97     cout << "白色人种会说话,一般都是单字节" << endl;
     98 }
     99 
    100 //BlackHuman.h
    101 
    102 #pragma once
    103 #include "ihuman.h"
    104 class CBlackHuman :
    105     public IHuman
    106 {
    107 public:
    108     CBlackHuman(void);
    109     ~CBlackHuman(void);
    110     void Laugh();
    111     void Cry();
    112     void Talk();
    113 };
    114 
    115 //BlackHuman.cpp
    116 
    117 #include "StdAfx.h"
    118 #include "BlackHuman.h"
    119 #include <iostream>
    120 using std::cout;
    121 using std::endl;
    122 CBlackHuman::CBlackHuman(void)
    123 {
    124 }
    125 CBlackHuman::~CBlackHuman(void)
    126 {
    127 }
    128 void CBlackHuman::Cry()
    129 {
    130     cout << "黑人会哭" << endl;
    131 }
    132 void CBlackHuman::Laugh()
    133 {
    134     cout << "黑人会笑" << endl;
    135 }
    136 void CBlackHuman::Talk()
    137 {
    138     cout << "黑人可以说话,一般人听不懂" << endl;
    139 }
    140 
    141 //IHumanFactory.h
    142 
    143 #pragma once
    144 #include "IHuman.h"
    145 class IHumanFactory
    146 {
    147 public:
    148     IHumanFactory(void)
    149     {
    150     }
    151     virtual ~IHumanFactory(void)
    152     {
    153     }
    154     virtual IHuman * CreateHuman() = 0;
    155 };
    156 //YellowHuman.h
    157 
    158 #pragma once
    159 #include "ihumanfactory.h"
    160 class CYellowHumanFactory :
    161     public IHumanFactory
    162 {
    163 public:
    164     CYellowHumanFactory(void);
    165     ~CYellowHumanFactory(void);
    166     virtual IHuman * CreateHuman(void);
    167 };
    168 
    169 //YellowHumanFactory.cpp
    170 
    171 #include "StdAfx.h"
    172 #include "YellowHumanFactory.h"
    173 #include "YellowHuman.h"
    174 CYellowHumanFactory::CYellowHumanFactory(void)
    175 {
    176 }
    177 CYellowHumanFactory::~CYellowHumanFactory(void)
    178 {
    179 }
    180 IHuman * CYellowHumanFactory::CreateHuman( void )
    181 {
    182     return new CYellowHuman();
    183 }
    184 //WhiteHuman.h
    185 
    186 #pragma once
    187 #include "ihumanfactory.h"
    188 class CWhiteHumanFactory :
    189     public IHumanFactory
    190 {
    191 public:
    192     CWhiteHumanFactory(void);
    193     ~CWhiteHumanFactory(void);
    194     virtual IHuman * CreateHuman(void);
    195 };
    196 
    197 //WhiteHumanFactory.cpp
    198 
    199 #include "StdAfx.h"
    200 #include "WhiteHumanFactory.h"
    201 #include "WhiteHuman.h"
    202 CWhiteHumanFactory::CWhiteHumanFactory(void)
    203 {
    204 }
    205 CWhiteHumanFactory::~CWhiteHumanFactory(void)
    206 {
    207 }
    208 IHuman * CWhiteHumanFactory::CreateHuman( void )
    209 {
    210     return new CWhiteHuman();
    211 }
    212 //BlackHuman.h
    213 
    214 #pragma once
    215 #include "ihumanfactory.h"
    216 class CBlackHumanFactory :
    217     public IHumanFactory
    218 {
    219 public:
    220     CBlackHumanFactory(void);
    221     ~CBlackHumanFactory(void);
    222     virtual IHuman * CreateHuman();
    223 };
    224 //BlackHumanFactory.cpp
    225 
    226 #include "StdAfx.h"
    227 #include "BlackHumanFactory.h"
    228 #include "BlackHuman.h"
    229 CBlackHumanFactory::CBlackHumanFactory(void)
    230 {
    231 }
    232 CBlackHumanFactory::~CBlackHumanFactory(void)
    233 {
    234 }
    235 IHuman * CBlackHumanFactory::CreateHuman()
    236 {
    237     return new CBlackHuman();
    238 }
    239 
    240 //FactoryMethod.cpp
    241 
    242 // FactoryMethod.cpp : 定义控制台应用程序的入口点。
    243 //
    244 #include "stdafx.h"
    245 #include "IHuman.h"
    246 #include "YellowHuman.h"
    247 #include "WhiteHuman.h"
    248 #include "BlackHuman.h"
    249 #include "SimpleHumanFactory.h"
    250 #include "StandardHumanFactory.h"
    251 #include "IHumanFactory.h"
    252 #include "YellowHumanFactory.h"
    253 #include "WhiteHumanFactory.h"
    254 #include "BlackHumanFactory.h"
    255 #include <iostream>
    256 using std::cout;
    257 using std::endl;
    258 using std::string;
    259 void DoFactoryMethod1()
    260 {
    261     cout << "----------第一批人是这样的:黄种人工厂来生产黄种人" << endl;
    262     IHumanFactory *pHumanFactory = new CYellowHumanFactory();
    263     IHuman *pHuman = pHumanFactory->CreateHuman();
    264     pHuman->Cry();
    265     pHuman->Laugh();
    266     pHuman->Talk();
    267     delete pHuman;
    268     delete pHumanFactory;
    269 }
    270 void DoFactoryMethod2()
    271 {
    272     cout << "----------第二批人是这样的:白种人工厂来生产白种人" << endl;
    273     IHumanFactory *pHumanFactory = new CWhiteHumanFactory();
    274     IHuman *pHuman = pHumanFactory->CreateHuman();
    275     pHuman->Cry();
    276     pHuman->Laugh();
    277     pHuman->Talk();
    278     delete pHuman;
    279     delete pHumanFactory;
    280 }
    281 void DoFactoryMethod3()
    282 {
    283     cout << "----------第一批人是这样的:黑种人工厂来生产黑种人" << endl;
    284     IHumanFactory *pHumanFactory = new CBlackHumanFactory();
    285     IHuman *pHuman = pHumanFactory->CreateHuman();
    286     pHuman->Cry();
    287     pHuman->Laugh();
    288     pHuman->Talk();
    289     delete pHuman;
    290     delete pHumanFactory;
    291 }
    292 int _tmain(int argc, _TCHAR* argv[])
    293 {
    294     //工厂方法
    295     cout << "----------工厂方法:" << endl;
    296     DoFactoryMethod1();
    297     DoFactoryMethod2();
    298     DoFactoryMethod3();
    299     
    300     _CrtSetDbgFlag(_CRTDBG_LEAK_CHECK_DF | _CRTDBG_ALLOC_MEM_DF);
    301     _CrtDumpMemoryLeaks();
    302     return 0;
    303 }
    View Code

    实现方式2所谓的简单工厂模式,通过参数传递来决定要创建哪一个具体产品。

    若不需延迟实例化(将实例化放到子类中),则在Factory中增加对应的创建方法即可,如:Product* CreateConcreteProduct(int i);

    若需要延迟实例化,则在抽象Factory与具体ConcreteFactory中增加相应方法,在ConcreteFactory中实现方法Product* CreateConcreteProduct(int i)

    优点:无需新增产品工厂类ConcreteFactory

    缺点:需要修改已有代码,存在风险

    代码如下:

      1 //Product.h
      2 // Product.h: interface for the Product class.
      3 //
      4 //////////////////////////////////////////////////////////////////////
      5 
      6 #if !defined(AFX_PRODUCT_H__714E1D10_AFA3_473E_A16C_759490E60B92__INCLUDED_)
      7 #define AFX_PRODUCT_H__714E1D10_AFA3_473E_A16C_759490E60B92__INCLUDED_
      8 
      9 #if _MSC_VER > 1000
     10 #pragma once
     11 #endif // _MSC_VER > 1000
     12 
     13 class Product  
     14 {
     15 public:
     16     Product();
     17     virtual ~Product();
     18 
     19 };
     20 
     21 class ConcreteProduct : public Product  
     22 {
     23 public:
     24     ConcreteProduct();
     25     virtual ~ConcreteProduct();
     26 
     27 };
     28 
     29 class ConcreteProduct1 : public Product  
     30 {
     31 public:
     32     ConcreteProduct1();
     33     virtual ~ConcreteProduct1();
     34 
     35 };
     36 
     37 #endif // !defined(AFX_PRODUCT_H__714E1D10_AFA3_473E_A16C_759490E60B92__INCLUDED_)
     38 
     39 
     40 
     41 //Product.cpp
     42 // Product.cpp: implementation of the Product class.
     43 //
     44 //////////////////////////////////////////////////////////////////////
     45 
     46 #include "Product.h"
     47 #include <iostream>
     48 
     49 using namespace std;
     50 
     51 //////////////////////////////////////////////////////////////////////
     52 // Construction/Destruction
     53 //////////////////////////////////////////////////////////////////////
     54 
     55 Product::Product()
     56 {
     57 }
     58 
     59 Product::~Product()
     60 {
     61 }
     62 
     63 ConcreteProduct::ConcreteProduct()
     64 {
     65     cout<<"ConcreteProduct..."<<endl;
     66 }
     67 
     68 ConcreteProduct::~ConcreteProduct()
     69 {
     70 }
     71 
     72 ConcreteProduct1::ConcreteProduct1()
     73 {
     74     cout<<"ConcreteProduct1..."<<endl;
     75 }
     76 
     77 ConcreteProduct1::~ConcreteProduct1()
     78 {
     79 }
     80 
     81 
     82 //Factory.h
     83 
     84 #if !defined(AFX_FACTORY_H__32B11FEA_57A7_484E_B289_AB0E12783D7D__INCLUDED_)
     85 #define AFX_FACTORY_H__32B11FEA_57A7_484E_B289_AB0E12783D7D__INCLUDED_
     86 
     87 #if _MSC_VER > 1000
     88 #pragma once
     89 #endif // _MSC_VER > 1000
     90 
     91 class Product;
     92 class Factory
     93 {
     94 public:
     95     virtual Product* CreateConcreteProduct(int i)=0;
     96     Factory();
     97     virtual ~Factory() = 0;
     98     virtual Product* CreateProduct() = 0;
     99     virtual Product* CreateProduct1() = 0;
    100 };
    101 
    102 class ConcreteFactory : public Factory  
    103 {
    104 public:
    105     ConcreteFactory();
    106     virtual ~ConcreteFactory();
    107     virtual Product* CreateProduct();
    108     virtual Product* CreateProduct1();
    109     virtual Product* CreateConcreteProduct(int i);
    110 };
    111 
    112 #endif // !defined(AFX_FACTORY_H__32B11FEA_57A7_484E_B289_AB0E12783D7D__INCLUDED_)
    113 
    114 
    115 //Factory.cpp
    116 
    117 // Factory.cpp: implementation of the Factory class.
    118 //
    119 //////////////////////////////////////////////////////////////////////
    120 
    121 #include "Factory.h"
    122 #include "Product.h" 
    123 #include <iostream>
    124 
    125 using namespace std;
    126 
    127 //////////////////////////////////////////////////////////////////////
    128 // Construction/Destruction
    129 //////////////////////////////////////////////////////////////////////
    130 
    131 Factory::Factory()
    132 {
    133 }
    134 
    135 Factory::~Factory()
    136 {
    137 }
    138 
    139 ConcreteFactory::ConcreteFactory()
    140 {
    141     cout<<"ConcreteFactory..."<<endl;
    142 }
    143 
    144 ConcreteFactory::~ConcreteFactory()
    145 {
    146 }
    147 
    148 Product* ConcreteFactory::CreateProduct()
    149 {
    150     return new ConcreteProduct();
    151 }
    152 
    153 Product* ConcreteFactory::CreateProduct1()
    154 {
    155     return new ConcreteProduct1();
    156 }
    157 
    158 
    159 Product* ConcreteFactory::CreateConcreteProduct(int i)
    160 {
    161     Product* pProduct = NULL;
    162     switch(i)
    163     {
    164     case 0:
    165         pProduct = new ConcreteProduct();
    166         break;
    167     case 1:
    168         pProduct = new ConcreteProduct1();
    169         break;
    170     default:
    171         break;
    172     }
    173     return pProduct;
    174 }
    175 
    176 //main.cpp
    177 #include "Factory.h"
    178 #include "Product.h"
    179 #include <iostream>
    180 
    181 using namespace std;
    182 
    183 int main()
    184 {
    185     Factory* pFactory = new ConcreteFactory();
    186 
    187     Product* pProduct = pFactory->CreateProduct1();
    188 
    189     //Product* pProduct = pFactory->CreateConcreteProduct(1);
    190     return 0;
    191 }
    View Code

    若要为不同类的类提供一个创建对象的接口,要用AbstractFactory。


    工厂模式主要是为创建对象提供过渡接口,以便将创建对象的具体过程屏蔽隔离起来,达到提高灵活性的目的。
    工厂模式可以分为三类:
    1)简单工厂模式(Simple Factory)
    2)工厂方法模式(Factory Method)
    3)抽象工厂模式(Abstract Factory)
             这三种模式从上到下逐步抽象,并且更具一般性。
            GOF在《设计模式》一书中将工厂模式分为两类:工厂方法模式(Factory Method)与抽象工厂模式(Abstract Factory)。将简单工厂模式(Simple Factory)看为工厂方法模式的一种特例,两者归为一类。


    区别
    工厂方法模式:
    一个抽象产品类,可以派生出多个具体产品类。   
    一个抽象工厂类,可以派生出多个具体工厂类。   
    每个具体工厂类只能创建一个具体产品类的实例。
    抽象工厂模式:
    多个抽象产品类,每个抽象产品类可以派生出多个具体产品类。   
    一个抽象工厂类,可以派生出多个具体工厂类。   
    每个具体工厂类可以创建多个具体产品类的实例。   
    区别:
    工厂方法模式只有一个抽象产品类,而抽象工厂模式有多个。   
    工厂方法模式的具体工厂类只能创建一个具体产品类的实例,而抽象工厂模式可以创建多个。
    两者皆可。

  • 相关阅读:
    笑话(真人真事)一则
    Object Builder中的Locator究竟是不是采用Composite的模式之我见
    C++AndC#我的程序员之路
    C#中各种十进制数的转换
    使用GotDotnet workSpace手记
    检索 COM 类工厂中 CLSID 为 {0002450000000000C000000000000046} 的组件失败
    CSS如何让同一行的图片和文字垂直居中对齐(FF,Safari,IE都通过)
    怎样练习一万小时成为顶级高手?
    CSS控制大小写
    做SEO权重计算公式
  • 原文地址:https://www.cnblogs.com/jiese/p/3154669.html
Copyright © 2020-2023  润新知