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 }
實現方式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 }
若要為不同類的類提供一個創建對象的接口,要用AbstractFactory。
工廠模式主要是為創建對象提供過渡接口,以便將創建對象的具體過程屏蔽隔離起來,達到提高靈活性的目的。
工廠模式可以分為三類:
1)簡單工廠模式(Simple Factory)
2)工廠方法模式(Factory Method)
3)抽象工廠模式(Abstract Factory)
這三種模式從上到下逐步抽象,並且更具一般性。
GOF在《設計模式》一書中將工廠模式分為兩類:工廠方法模式(Factory Method)與抽象工廠模式(Abstract Factory)。將簡單工廠模式(Simple Factory)看為工廠方法模式的一種特例,兩者歸為一類。
區別
工廠方法模式:
一個抽象產品類,可以派生出多個具體產品類。
一個抽象工廠類,可以派生出多個具體工廠類。
每個具體工廠類只能創建一個具體產品類的實例。
抽象工廠模式:
多個抽象產品類,每個抽象產品類可以派生出多個具體產品類。
一個抽象工廠類,可以派生出多個具體工廠類。
每個具體工廠類可以創建多個具體產品類的實例。
區別:
工廠方法模式只有一個抽象產品類,而抽象工廠模式有多個。
工廠方法模式的具體工廠類只能創建一個具體產品類的實例,而抽象工廠模式可以創建多個。
兩者皆可。