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)看為工廠方法模式的一種特例,兩者歸為一類。


區別
工廠方法模式:
一個抽象產品類,可以派生出多個具體產品類。   
一個抽象工廠類,可以派生出多個具體工廠類。   
每個具體工廠類只能創建一個具體產品類的實例。
抽象工廠模式:
多個抽象產品類,每個抽象產品類可以派生出多個具體產品類。   
一個抽象工廠類,可以派生出多個具體工廠類。   
每個具體工廠類可以創建多個具體產品類的實例。   
區別:
工廠方法模式只有一個抽象產品類,而抽象工廠模式有多個。   
工廠方法模式的具體工廠類只能創建一個具體產品類的實例,而抽象工廠模式可以創建多個。
兩者皆可。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM