C++设计模式-Factory工厂模式
来源:互联网 发布:拓扑图制作软件 编辑:程序博客网 时间:2024/06/05 17:07
Factory
1、定义创建对象的接口,封装对象的创建
2、将实际创建工作延迟到子类中,例如,类A中药使用类B,B是抽象父类,但是在类A中不知道具体要实例化哪一个B的子类,但是在类A的子类D中是可以知道的。在A中无法使用 new B***()方法
3、将创建工作延迟到子类中后,核心工厂类不再负责产品的创建,这样核心类成为一个抽象工厂,只提供工厂子类必须实现的接口,这样的好处是可以不用修改已有的工厂类的情况下增加新的产品(每一种产品,都分别对应相应的工厂子类负责其创建工作)
使用场景:用于一类类(所创建的产品继承共同的产品基类)的创建
实现方式1:所谓的工厂方法模式,对每一个子类产品都分别对应一个工厂子类,用来创建相应的产品,这样若增加了新的产品,只需相应增加工厂子类即可
优点:不用修改已有代码,开放封闭原则:对扩展开放,对更改封闭
代码如下:
//IHuman.h#pragma onceclass IHuman{public: IHuman(void) { } virtual ~IHuman(void) { } virtual void Laugh() = 0; virtual void Cry() = 0; virtual void Talk() = 0;};//YellowHuman.h#pragma once#include "ihuman.h"class CYellowHuman : public IHuman{public: CYellowHuman(void); ~CYellowHuman(void); void Laugh(); void Cry(); void Talk();};//YellowHuman.cpp#include "StdAfx.h"#include "YellowHuman.h"#include <iostream>using std::cout;using std::endl;CYellowHuman::CYellowHuman(void){}CYellowHuman::~CYellowHuman(void){}void CYellowHuman::Cry(){ cout << "黄色人种会哭" << endl;}void CYellowHuman::Laugh(){ cout << "黄色人种会大笑,幸福呀!" << endl;}void CYellowHuman::Talk(){ cout << "黄色人种会说话,一般说的都是双字节" << endl;}//WhiteHuman.h#pragma once#include "ihuman.h"class CWhiteHuman : public IHuman{public: CWhiteHuman(void); ~CWhiteHuman(void); void Laugh(); void Cry(); void Talk();};//WhiteHuman.cpp#include "StdAfx.h"#include "WhiteHuman.h"#include <iostream>using std::cout;using std::endl;CWhiteHuman::CWhiteHuman(void){}CWhiteHuman::~CWhiteHuman(void){}void CWhiteHuman::Cry(){ cout << "白色人种会哭" << endl;}void CWhiteHuman::Laugh(){ cout << "白色人种会大笑,侵略的笑声" << endl;}void CWhiteHuman::Talk(){ cout << "白色人种会说话,一般都是单字节" << endl;}//BlackHuman.h#pragma once#include "ihuman.h"class CBlackHuman : public IHuman{public: CBlackHuman(void); ~CBlackHuman(void); void Laugh(); void Cry(); void Talk();};//BlackHuman.cpp#include "StdAfx.h"#include "BlackHuman.h"#include <iostream>using std::cout;using std::endl;CBlackHuman::CBlackHuman(void){}CBlackHuman::~CBlackHuman(void){}void CBlackHuman::Cry(){ cout << "黑人会哭" << endl;}void CBlackHuman::Laugh(){ cout << "黑人会笑" << endl;}void CBlackHuman::Talk(){ cout << "黑人可以说话,一般人听不懂" << endl;}//IHumanFactory.h#pragma once#include "IHuman.h"class IHumanFactory{public: IHumanFactory(void) { } virtual ~IHumanFactory(void) { } virtual IHuman * CreateHuman() = 0;};//YellowHuman.h#pragma once#include "ihumanfactory.h"class CYellowHumanFactory : public IHumanFactory{public: CYellowHumanFactory(void); ~CYellowHumanFactory(void); virtual IHuman * CreateHuman(void);};//YellowHumanFactory.cpp#include "StdAfx.h"#include "YellowHumanFactory.h"#include "YellowHuman.h"CYellowHumanFactory::CYellowHumanFactory(void){}CYellowHumanFactory::~CYellowHumanFactory(void){}IHuman * CYellowHumanFactory::CreateHuman( void ){ return new CYellowHuman();}//WhiteHuman.h#pragma once#include "ihumanfactory.h"class CWhiteHumanFactory : public IHumanFactory{public: CWhiteHumanFactory(void); ~CWhiteHumanFactory(void); virtual IHuman * CreateHuman(void);};//WhiteHumanFactory.cpp#include "StdAfx.h"#include "WhiteHumanFactory.h"#include "WhiteHuman.h"CWhiteHumanFactory::CWhiteHumanFactory(void){}CWhiteHumanFactory::~CWhiteHumanFactory(void){}IHuman * CWhiteHumanFactory::CreateHuman( void ){ return new CWhiteHuman();}//BlackHuman.h#pragma once#include "ihumanfactory.h"class CBlackHumanFactory : public IHumanFactory{public: CBlackHumanFactory(void); ~CBlackHumanFactory(void); virtual IHuman * CreateHuman();};//BlackHumanFactory.cpp#include "StdAfx.h"#include "BlackHumanFactory.h"#include "BlackHuman.h"CBlackHumanFactory::CBlackHumanFactory(void){}CBlackHumanFactory::~CBlackHumanFactory(void){}IHuman * CBlackHumanFactory::CreateHuman(){ return new CBlackHuman();}//FactoryMethod.cpp// FactoryMethod.cpp : 定义控制台应用程序的入口点。//#include "stdafx.h"#include "IHuman.h"#include "YellowHuman.h"#include "WhiteHuman.h"#include "BlackHuman.h"#include "SimpleHumanFactory.h"#include "StandardHumanFactory.h"#include "IHumanFactory.h"#include "YellowHumanFactory.h"#include "WhiteHumanFactory.h"#include "BlackHumanFactory.h"#include <iostream>using std::cout;using std::endl;using std::string;void DoFactoryMethod1(){ cout << "----------第一批人是这样的:黄种人工厂来生产黄种人" << endl; IHumanFactory *pHumanFactory = new CYellowHumanFactory(); IHuman *pHuman = pHumanFactory->CreateHuman(); pHuman->Cry(); pHuman->Laugh(); pHuman->Talk(); delete pHuman; delete pHumanFactory;}void DoFactoryMethod2(){ cout << "----------第二批人是这样的:白种人工厂来生产白种人" << endl; IHumanFactory *pHumanFactory = new CWhiteHumanFactory(); IHuman *pHuman = pHumanFactory->CreateHuman(); pHuman->Cry(); pHuman->Laugh(); pHuman->Talk(); delete pHuman; delete pHumanFactory;}void DoFactoryMethod3(){ cout << "----------第一批人是这样的:黑种人工厂来生产黑种人" << endl; IHumanFactory *pHumanFactory = new CBlackHumanFactory(); IHuman *pHuman = pHumanFactory->CreateHuman(); pHuman->Cry(); pHuman->Laugh(); pHuman->Talk(); delete pHuman; delete pHumanFactory;}int _tmain(int argc, _TCHAR* argv[]){ //工厂方法 cout << "----------工厂方法:" << endl; DoFactoryMethod1(); DoFactoryMethod2(); DoFactoryMethod3(); _CrtSetDbgFlag(_CRTDBG_LEAK_CHECK_DF | _CRTDBG_ALLOC_MEM_DF); _CrtDumpMemoryLeaks(); return 0;}
实现方式2:所谓的简单工厂模式,通过参数传递来决定要创建哪一个具体产品。
若不需延迟实例化(将实例化放到子类中),则在Factory中增加对应的创建方法即可,如:Product* CreateConcreteProduct(int i);
若需要延迟实例化,则在抽象Factory与具体ConcreteFactory中增加相应方法,在ConcreteFactory中实现方法Product* CreateConcreteProduct(int i)
优点:无需新增产品工厂类ConcreteFactory
缺点:需要修改已有代码,存在风险
代码如下:
//Product.h// Product.h: interface for the Product class.////////////////////////////////////////////////////////////////////////#if !defined(AFX_PRODUCT_H__714E1D10_AFA3_473E_A16C_759490E60B92__INCLUDED_)#define AFX_PRODUCT_H__714E1D10_AFA3_473E_A16C_759490E60B92__INCLUDED_#if _MSC_VER > 1000#pragma once#endif // _MSC_VER > 1000class Product {public: Product(); virtual ~Product();};class ConcreteProduct : public Product {public: ConcreteProduct(); virtual ~ConcreteProduct();};class ConcreteProduct1 : public Product {public: ConcreteProduct1(); virtual ~ConcreteProduct1();};#endif // !defined(AFX_PRODUCT_H__714E1D10_AFA3_473E_A16C_759490E60B92__INCLUDED_)//Product.cpp// Product.cpp: implementation of the Product class.////////////////////////////////////////////////////////////////////////#include "Product.h"#include <iostream>using namespace std;//////////////////////////////////////////////////////////////////////// Construction/Destruction//////////////////////////////////////////////////////////////////////Product::Product(){}Product::~Product(){}ConcreteProduct::ConcreteProduct(){ cout<<"ConcreteProduct..."<<endl;}ConcreteProduct::~ConcreteProduct(){}ConcreteProduct1::ConcreteProduct1(){ cout<<"ConcreteProduct1..."<<endl;}ConcreteProduct1::~ConcreteProduct1(){}//Factory.h#if !defined(AFX_FACTORY_H__32B11FEA_57A7_484E_B289_AB0E12783D7D__INCLUDED_)#define AFX_FACTORY_H__32B11FEA_57A7_484E_B289_AB0E12783D7D__INCLUDED_#if _MSC_VER > 1000#pragma once#endif // _MSC_VER > 1000class Product;class Factory{public: virtual Product* CreateConcreteProduct(int i)=0; Factory(); virtual ~Factory() = 0; virtual Product* CreateProduct() = 0; virtual Product* CreateProduct1() = 0;};class ConcreteFactory : public Factory {public: ConcreteFactory(); virtual ~ConcreteFactory(); virtual Product* CreateProduct(); virtual Product* CreateProduct1(); virtual Product* CreateConcreteProduct(int i);};#endif // !defined(AFX_FACTORY_H__32B11FEA_57A7_484E_B289_AB0E12783D7D__INCLUDED_)//Factory.cpp// Factory.cpp: implementation of the Factory class.////////////////////////////////////////////////////////////////////////#include "Factory.h"#include "Product.h" #include <iostream>using namespace std;//////////////////////////////////////////////////////////////////////// Construction/Destruction//////////////////////////////////////////////////////////////////////Factory::Factory(){}Factory::~Factory(){}ConcreteFactory::ConcreteFactory(){ cout<<"ConcreteFactory..."<<endl;}ConcreteFactory::~ConcreteFactory(){}Product* ConcreteFactory::CreateProduct(){ return new ConcreteProduct();}Product* ConcreteFactory::CreateProduct1(){ return new ConcreteProduct1();}Product* ConcreteFactory::CreateConcreteProduct(int i){ Product* pProduct = NULL; switch(i) { case 0: pProduct = new ConcreteProduct(); break; case 1: pProduct = new ConcreteProduct1(); break; default: break; } return pProduct;}//main.cpp#include "Factory.h"#include "Product.h"#include <iostream>using namespace std;int main(){ Factory* pFactory = new ConcreteFactory(); Product* pProduct = pFactory->CreateProduct1(); //Product* pProduct = pFactory->CreateConcreteProduct(1); return 0;}
若要为不同类的类提供一个创建对象的接口,要用AbstractFactory。
工厂模式主要是为创建对象提供过渡接口,以便将创建对象的具体过程屏蔽隔离起来,达到提高灵活性的目的。
工厂模式可以分为三类:
1)简单工厂模式(Simple Factory)
2)工厂方法模式(Factory Method)
3)抽象工厂模式(Abstract Factory)
这三种模式从上到下逐步抽象,并且更具一般性。
GOF在《设计模式》一书中将工厂模式分为两类:工厂方法模式(Factory Method)与抽象工厂模式(Abstract Factory)。将简单工厂模式(Simple Factory)看为工厂方法模式的一种特例,两者归为一类。
区别
工厂方法模式:
一个抽象产品类,可以派生出多个具体产品类。
一个抽象工厂类,可以派生出多个具体工厂类。
每个具体工厂类只能创建一个具体产品类的实例。
抽象工厂模式:
多个抽象产品类,每个抽象产品类可以派生出多个具体产品类。
一个抽象工厂类,可以派生出多个具体工厂类。
每个具体工厂类可以创建多个具体产品类的实例。
区别:
工厂方法模式只有一个抽象产品类,而抽象工厂模式有多个。
工厂方法模式的具体工厂类只能创建一个具体产品类的实例,而抽象工厂模式可以创建多个。
两者皆可。
- 工厂设计模式 factory
- [设计模式]Factory工厂模式
- 设计模式--工厂模式Factory
- 设计模式 -- 工厂模式(Factory)
- 设计模式--工厂模式Factory
- 设计模式 - Factory工厂模式
- 乐在其中设计模式(C#) - 工厂方法模式(Factory Method Pattern)
- 乐在其中设计模式(C#) - 抽象工厂模式(Abstract Factory Pattern)
- 设计模式C++(Factory Method工厂方法模式)
- 工厂设计模式(Factory Pattern)
- Java设计模式:Factory(工厂模式)
- 设计模式之Factory工厂模式
- 设计模式(1)-工厂模式(Factory)
- 设计模式(1)-工厂模式(Factory)
- 设计模式之工厂模式Factory
- DAO设计模式+工厂模式(Factory)
- 设计模式之Factory工厂模式
- java设计模式之工厂模式(Factory)
- 局豆构巢芬吞疚厮采柑沮偌匾垢帕
- 氯沸研猛适煞阶趟腿胶稼概翟怂热
- 磕幽仪父侣嚎乔剂刈习且扔妹图疵
- 2015年IT业薪酬展望:开发、技术支持、项目经理……
- d2 关键字 标识符定义规范 常量变量 作用域 printf scanf
- C++设计模式-Factory工厂模式
- Java--方法参数的传递
- 3-4-3 猜数游戏 (开口中)
- 细节&&态度(考试系统导人员收获)
- UVA 1252 Twenty Questions 状态压缩dp 记忆化搜索
- vim实用技巧学习笔记(3.不要自我重复)
- 算法导论之求股票最大收益
- 系统切换过程的数据库导换
- 运用RUP 4+1视图方法进行软件架构设计