cly

博客园 首页 新随笔 联系 订阅 管理

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)看为工厂方法模式的一种特例,两者归为一类。


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

posted on 2013-06-25 14:46  戒色  阅读(13722)  评论(3编辑  收藏  举报