抽象工厂概述
在抽象工厂模式中,定义了一个抽象工厂类,它提供了创建一组对象的接口,这种模式适合解决多个不同产品系列的问题,抽象工厂定义如下:
抽象工厂模式:提供一个创建一系列相关或相互依赖对象的接口,而无须指定它们具体的类,其基本UML类图如下:
在抽象工厂模式结构图中包含如下几个角色:
AbstractFactory(抽象工厂):它声明了一组用于创建不同类别产品的抽象方法,每一个方法对应一类产品。
ConcreteFactory(具体工厂):它实现了在抽象工厂中声明的创建产品的方法,生成具体产品。
- AbstractProduct(抽象产品):它为每种产品声明接口,在抽象产品中声明了产品所具有的业务方法。
- ConcreteProduct(具体产品):它定义具体工厂生产的具体产品对象,实现抽象产品接口中声明的业务方法。
在抽象工厂中声明了多个工厂方法,用于创建不同类型的产品,抽象工厂可以是接口,也可以是抽象类或者具体类.
模拟场景
我们都知道富士康是一家电子代工厂,它可以代工生产各类电子产品,比如电视、手机、冰箱等。当设计厂家提交订单给富士康时,富士康会为各个厂家搭建各自的生产线,现在模拟其生产过程,UML设计图如下:
uml类图说明:
- CAbsFactory类中的抽象接口代表了富士康工厂具备的生产能力;
- TCLProduct类和XiaomiProduct类代表TCL和小米设计厂家;
- CAbstractPhone类代表手机具备的公共特征;
- 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);
}
运行结果:
抽象工厂总结
优点:
- 抽象工厂在新增其他的具体工厂类符合“开放扩展-关闭修改”原则;比如新增华为品牌手机和电视,只需要新增具体的工厂类和产品类即可,不需要修改其他代码;
- 创建具体产品实例过程和客户端分离,且客户端是面对抽象接口进行编程,易于进行整体更换;
缺点:
- 抽象工厂最大的不足就是新增抽象接口,以完成某个额外的产品;比如让富士康增加生成汽车的接口,对整体系统影响很大;比如需要在抽象工厂类中增加生成汽车接口,甚至需要修改具体工厂类;
适用场景:
- 抽象工厂适合解决需要“创建多个种类的产品”的场合;