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)看为工厂方法模式的一种特例,两者归为一类。
区别
工厂方法模式:
一个抽象产品类,可以派生出多个具体产品类。
一个抽象工厂类,可以派生出多个具体工厂类。
每个具体工厂类只能创建一个具体产品类的实例。
抽象工厂模式:
多个抽象产品类,每个抽象产品类可以派生出多个具体产品类。
一个抽象工厂类,可以派生出多个具体工厂类。
每个具体工厂类可以创建多个具体产品类的实例。
区别:
工厂方法模式只有一个抽象产品类,而抽象工厂模式有多个。
工厂方法模式的具体工厂类只能创建一个具体产品类的实例,而抽象工厂模式可以创建多个。
两者皆可。