抽象工厂模式是所有形态的工厂模式中最为抽象和最具一般性的一种形态。
举例说明:Abstract Factory模式说的是抽象工厂,抽象工厂中继承出了两个实际工厂,这两个实际工厂开始生产对象,两个工厂生产出来的对象风格不同,比如游戏开发中,有一个古典物品工厂,一个现代物品工厂,他们都派生于抽象工厂,都实现了创建计算工具这个方法,而古典工厂中的创建计算工具将返回一个算盘,而现代工厂返回的计算工具是一个计算器,古典工厂中创建的商人是一身汉服的店小二,现代工厂创建的商人是一身西装的小老板,这样在实际游戏中先实例化一个古典工厂,就可以依靠古典工厂得到身穿汉服拿着算盘的店小二,或者依靠现代工厂得到身穿西装拿着计算器的小老板,而不会得到一个身穿汉服却拿着计算器的店小二或者身穿西装而抱着算盘的小老板。
这样看来,Abstract Factory模式最主要的是抽象工厂的实例工厂们可以产生一系列相互依赖或相互协调的对象,Abstract Factory模式存在的意义就是为了创建各系列的对象而存在的。相对Factory Method模式的解决“单个对象”的需求变化,Abstract Factory模式解决“系列相关对象”的需求变化。
抽象工厂模式中的4中不同角色:
抽象工厂(Abstract Factory):它与应用系统商业逻辑无关。
具体工厂(Concrete Factory):这个角色直接在客户端的调用下创建产品的实例。这个角色含有选择合适的产品对象的逻辑,而这个逻辑是与应用系统的商业逻辑紧密相关的。
抽象产品(Abstract Product):担任这个角色的类是工厂方法模式所创建的对象的父类,或它们共同拥有的接口。
具体产品(Concrete Product):抽象工厂模式所创建的任何产品对象都是某一个具体产品类的实例。这是客户端最终需要的东西,其内部一定充满了应用系统的商业逻辑。
下面是Abstract Factory的UML类图:
C++代码实现:
// AbstractFactory.h
#include <iostream>
#include <string>
#include <memory>
using namespace std;
// 一个产品抽象类,比如对应AbstractProductA
class Dress
{
protected:
string dress_style;
public:
Dress(const string dress_style) : dress_style(dress_style)
{
}
virtual string get_dress() const = 0;
virtual ~Dress()
{
cout << "in destructor of Dress..." << endl;
}
};
// 一个具体产品类,比如ProductA1
class AntiqueDress : public Dress
{
public:
AntiqueDress() : Dress("汉服")
{
}
string get_dress() const
{
return dress_style;
}
~AntiqueDress()
{
cout << "in destructor of AntiqueDress..." << endl;
}
};
// 一个具体产品类,比如ProductA2
class ModernDress : public Dress
{
public:
ModernDress() : Dress("西装")
{
}
string get_dress() const
{
return dress_style;
}
~ModernDress()
{
cout << "in destructor of ModernDress..." << endl;
}
};
// 一个产品抽象类,比如对应AbstractProductB
class Calculator
{
protected:
string calculator_style;
public:
Calculator(const string calculator_style) : calculator_style(calculator_style)
{
}
virtual string get_calculator() const = 0;
virtual ~Calculator()
{
cout << "in destructor of Calculator..." << endl;
}
};
// 一个具体产品类,比如ProductB1
class AntiqueCalculator : public Calculator
{
public:
AntiqueCalculator() : Calculator("算盘")
{
}
string get_calculator() const
{
return calculator_style;
}
~AntiqueCalculator()
{
cout << "in destructor of AntiqueCalculator..." << endl;
}
};
// 一个具体产品类,比如ProductB2
class ModernCalculator : public Calculator
{
public:
ModernCalculator() : Calculator("电子计算器")
{
}
string get_calculator() const
{
return calculator_style;
}
~ModernCalculator()
{
cout << "in destructor of ModernCalculator..." << endl;
}
};
// 一个抽象工厂类,比如AbstractFactory
class FigureFactory
{
public:
virtual auto_ptr<Dress> create_dress() = 0;
virtual auto_ptr<Calculator> create_calculator() = 0;
virtual ~FigureFactory()
{
cout << "in destructor of FigureFactory..." << endl;
}
};
// 一个具体工厂类,比如ConcreteFactory1
class AntiqueFigureFactory : public FigureFactory
{
auto_ptr<Dress> create_dress()
{
auto_ptr<Dress> dress(new AntiqueDress);
return dress;
}
auto_ptr<Calculator> create_calculator()
{
auto_ptr<Calculator> calculator(new AntiqueCalculator);
return calculator;
}
~AntiqueFigureFactory()
{
cout << "in destructor of AntiqueFigureFactory..." << endl;
}
};
// 一个具体工厂类,比如ConcreteFactory2
class ModernFigureFactory : public FigureFactory
{
auto_ptr<Dress> create_dress()
{
auto_ptr<Dress> dress(new ModernDress);
return dress;
}
auto_ptr<Calculator> create_calculator()
{
auto_ptr<Calculator> calculator(new ModernCalculator);
return calculator;
}
~ModernFigureFactory()
{
cout << "in destructor of ModernFigureFactory..." << endl;
}
};
// 测试代码:AbstractFactory.cpp
#include "AbstractFactory.h"
int main(int argc, char** argv)
{
auto_ptr<Dress> dress;
auto_ptr<Calculator> calculator;
auto_ptr<FigureFactory> figurefactory;
auto_ptr<FigureFactory> ff1(new ModernFigureFactory);
figurefactory = ff1;
auto_ptr<Dress> d1(figurefactory->create_dress());
dress = d1;
auto_ptr<Calculator> c1(figurefactory->create_calculator());
calculator = c1;
cout << "现代人物的衣物:\t" << dress->get_dress() << "\t" << endl;
cout << "现代人物的计算器:\t" << calculator->get_calculator() << "\t" << endl;
cout << "-------------------------------------------" << endl;
auto_ptr<FigureFactory> ff2(new AntiqueFigureFactory);
figurefactory = ff2;
auto_ptr<Dress> d2(figurefactory->create_dress());
dress = d2;
auto_ptr<Calculator> c2(figurefactory->create_calculator());
calculator = c2;
cout << "古代人物的衣物:\t" << dress->get_dress() << "\t\t" << endl;
cout << "古代人物的计算器:\t" << calculator->get_calculator() << "\t" << endl;
return 0;
}
创建现代人物对象和创建古代人物对象时,只有带下划线的两句不同(可以作为参数传入或在配置文件中进行相关设计),其他都是一样的。因此,对于客户端程序而言,面对的仅仅是3个抽象类Dress、Calculator和FigureFactory了,而抽象类的接口要比具体实现类的接口稳定,这样就等于封装了变化。
开始出的UML类图和上面实现代码中各类之间的对应关系:
AbstractProductA < ---- > Dress
ProductA1 < ---- > AntiqueDress
ProductA2 < ---- > ModernDress
AbstractProductB < ---- > Calculator
ProductB1 < ---- > AntiqueCalculator
ProductB2 < ---- > ModernCalculator
AbstractFactory < ---- > FigureFactory
ConcreteFactory1 < ---- > AntiqueFigureFactory
ConcreteFactory2 < ---- > ModernFigureFactory
上述程序的输出结果:
现代人物的衣物: 西装
现代人物的计算器: 电子计算器
-------------------------------------------
in destructor of ModernFigureFactory...
in destructor of FigureFactory...
in destructor of ModernDress...
in destructor of Dress...
in destructor of ModernCalculator...
in destructor of Calculator...
古代人物的衣物: 汉服
古代人物的计算器: 算盘
in destructor of AntiqueFigureFactory...
in destructor of FigureFactory...
in destructor of AntiqueCalculator...
in destructor of Calculator...
in destructor of AntiqueDress...
in destructor of Dress...
实际中,没有必要输出析构函数中的内容。之所以这么做,是为了说明使用了auto_ptr会将有关动态分配的内存自动释放,而不至于造成内存泄漏。
最后再说明一下:
AbstractFactory.h中各类的代码应当分布在不同的文件中,这样在有扩展的时候,就不会修改该文件,而是另外增加两个文件(一个具体产品类,一个具体产品工厂)。这样做的目的,一方是因为OCP,另外一方面是可以大幅度提高编译效率。在本例中之所以这么做,纯粹是因为代码书写上的方便。