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

抽象工厂概述

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

抽象工厂模式:提供一个创建一系列相关或相互依赖对象的接口,而无须指定它们具体的类,其基本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

posted @ 2017-08-19 18:44  小怪兽&奥特曼  阅读(310)  评论(0编辑  收藏  举报