C++设计模式之抽象工厂模式

来源:互联网 发布:18*进入编程 编辑:程序博客网 时间:2024/06/08 07:22

抽象工厂概述

在抽象工厂模式中,定义了一个抽象工厂类,它提供了创建一组对象的接口,这种模式适合解决多个不同产品系列的问题,抽象工厂定义如下:

抽象工厂模式:提供一个创建一系列相关或相互依赖对象的接口,而无须指定它们具体的类,其基本UML类图如下:
这里写图片描述

在抽象工厂模式结构图中包含如下几个角色:

  • AbstractFactory(抽象工厂):它声明了一组用于创建不同类别产品的抽象方法,每一个方法对应一类产品。

  • ConcreteFactory(具体工厂):它实现了在抽象工厂中声明的创建产品的方法,生成具体产品。

  • AbstractProduct(抽象产品):它为每种产品声明接口,在抽象产品中声明了产品所具有的业务方法。
  • ConcreteProduct(具体产品):它定义具体工厂生产的具体产品对象,实现抽象产品接口中声明的业务方法。

在抽象工厂中声明了多个工厂方法,用于创建不同类型的产品,抽象工厂可以是接口,也可以是抽象类或者具体类.

模拟场景

我们都知道富士康是一家电子代工厂,它可以代工生产各类电子产品,比如电视、手机、冰箱等。当设计厂家提交订单给富士康时,富士康会为各个厂家搭建各自的生产线,现在模拟其生产过程,UML设计图如下:

这里写图片描述

uml类图说明:

  1. CAbsFactory类中的抽象接口代表了富士康工厂具备的生产能力;
  2. TCLProduct类和XiaomiProduct类代表TCL和小米设计厂家;
  3. CAbstractPhone类代表手机具备的公共特征;
  4. CAbstractTV类代表电视机具备的公共特征;

具体代码:

主体代码:

#include "stdafx.h"using namespace std;//手机基类class CAbstractPhone{public:    CAbstractPhone(){}    virtual ~CAbstractPhone(){}    //身份识别    virtual void GetPhoneID()= 0;};//电视基类class CAbstractTV{public:    CAbstractTV(){}    virtual ~CAbstractTV(){}    //身份识别    virtual void GetTVID()= 0;};//子类: TCL电视机class TCLTV:public CAbstractTV{public:    TCLTV(){cout <<"Create TCL TV."<<endl;}    ~TCLTV(){}    virtual void GetTVID()    {        cout << "I am TCL TV." <<endl;    }};//子类: TCL手机class TCLPhone:public CAbstractPhone{public:    TCLPhone(){cout <<"Create TCL phone."<< endl;}    ~TCLPhone(){}    virtual void GetPhoneID()    {        cout << "I am TCL phone" <<endl;    }};//子类: 小米电视机class XiaomiTV:public CAbstractTV{public:    XiaomiTV(){cout <<"Create Xiaomi TV."<<endl;}    ~XiaomiTV(){}    virtual void GetTVID()    {        cout << "I am Xiaomi TV" <<endl;    }};//子类: 小米手机class XiaomiPhone:public CAbstractPhone{public:    XiaomiPhone(){cout <<"Create Xiao phone."<< endl;}    ~XiaomiPhone(){}    virtual void GetPhoneID()    {        cout << "I am Xiaomi phone" <<endl;    }};//代工厂的生产能力class CAbsFactory{public:      virtual CAbstractTV* CreateTV()=0;    virtual CAbstractPhone* CreatePhone()=0;};//TCL电子设备生产线class TCLProduct:public CAbsFactory{public:    virtual CAbstractTV* CreateTV()    {      return new TCLTV;    }    virtual CAbstractPhone* CreatePhone()    {        return new TCLPhone;    }};//小米电子设备生产线class XiaomiProduct:public CAbsFactory{public:    virtual CAbstractTV* CreateTV()    {         return new XiaomiTV;    }    virtual CAbstractPhone* CreatePhone()    {        return new XiaomiPhone;    }};

测试代码:

int _tmain(int argc, _TCHAR* argv[]){    //生产TCL产品    CAbsFactory* pTclFactory = new TCLProduct();    //生产手机    CAbstractPhone* pPhone = pTclFactory->CreatePhone();    //生产电视    CAbstractTV* pTV = pTclFactory->CreateTV();    //身份验证    pPhone->GetPhoneID();    pTV->GetTVID();    cout <<"\n";    //生产小米产品    CAbsFactory* pXiaomiFactory = new XiaomiProduct();    //生产小米手机    CAbstractPhone* pXiaoPhone = pXiaomiFactory->CreatePhone();    //生产小米电视    CAbstractTV* pXiaoTV = pXiaomiFactory->CreateTV();    //身份验证    pXiaoPhone->GetPhoneID();    pXiaoTV->GetTVID();    SAFE_DELETE_PTR(pTclFactory);    SAFE_DELETE_PTR(pPhone);    SAFE_DELETE_PTR(pTV);    SAFE_DELETE_PTR(pXiaomiFactory);    SAFE_DELETE_PTR(pXiaoPhone);    SAFE_DELETE_PTR(pXiaoTV);}

运行结果:

这里写图片描述

抽象工厂总结

优点:

  1. 抽象工厂在新增其他的具体工厂类符合“开放扩展-关闭修改”原则;比如新增华为品牌手机和电视,只需要新增具体的工厂类和产品类即可,不需要修改其他代码;
  2. 创建具体产品实例过程和客户端分离,且客户端是面对抽象接口进行编程,易于进行整体更换;

缺点:

  1. 抽象工厂最大的不足就是新增抽象接口,以完成某个额外的产品;比如让富士康增加生成汽车的接口,对整体系统影响很大;比如需要在抽象工厂类中增加生成汽车接口,甚至需要修改具体工厂类;

适用场景:

  1. 抽象工厂适合解决需要“创建多个种类的产品”的场合;

资料参考:http://blog.csdn.net/lovelion/article/details/17517213

原创粉丝点击