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


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



0 0
原创粉丝点击