抽象工厂模式(Abstract Factory)
意图:提供一个创建
一系列相关或相互依赖对象的接口。
之前的工厂方法模式,每增加一个产品,就需要增加一个具体产品类和一个对于工厂类。
对于一些情况,比如设计一个UI库,有按钮、滚动条等组件,为了让程序更加个性化,需要实现程序可以换皮肤的功能,比如蓝色主题、红色主题等,而且要便于拓展新的主题。
如果用工厂方法模式来实现的话,对每个组件都要一个相应的工厂类,而且各个组件之间是存在关联的,比如蓝色主题的button和scrollbar之间可以看出一些列的,要实现统一的话,分别管理各个工厂比较麻烦,这时候就可以用抽象工厂模式了。
相比工厂方法模式,抽象工厂模式提供了创建
一系列相关产品的接口,而不像工厂方法模式只提供创建
一种产品的接口。
对于这个例子,一个抽象工厂提供了创建Button、Scrollbar等产品的接口。
UML图:
C++实现:
#include <assert.h>
#include <iostream>
using namespace std;
class AbsButton {
public :
virtual void draw() = 0;
};
class AbsScrollBar {
public :
virtual void draw() = 0;
};
class WidgetFactory {
public :
virtual AbsButton * createButton() = 0;
virtual AbsScrollBar * createScrollBar() = 0;
};
class BlueButton : public AbsButton {
public :
virtual void draw() {
cout << "Blue Button" << endl;
}
};
class BlueScrollBar : public AbsScrollBar {
public :
virtual void draw() {
cout << "Blue ScrollBar" << endl;
}
};
class BlueWidgetFactory : public WidgetFactory {
public :
virtual AbsButton * createButton() {
return new BlueButton();
}
virtual AbsScrollBar * createScrollBar() {
return new BlueScrollBar();
}
};
class RedButton : public AbsButton {
public :
virtual void draw() {
cout << "Red Button" << endl;
}
};
class RedScrollBar : public AbsScrollBar {
public :
virtual void draw() {
cout << "Red ScrollBar" << endl;
}
};
class RedWidgetFactory : public WidgetFactory {
public :
virtual AbsButton * createButton() {
return new RedButton();
}
virtual AbsScrollBar * createScrollBar() {
return new RedScrollBar();
}
};
int main() {
WidgetFactory * factory = new BlueWidgetFactory();
assert(factory != NULL);
AbsButton * button = factory->createButton();
assert(button != NULL);
AbsScrollBar * scrollbar = factory->createScrollBar();
assert(scrollbar != NULL);
button->draw();
scrollbar->draw();
delete factory;
factory = NULL;
factory = new RedWidgetFactory();
assert(factory != NULL);
delete button;
button = NULL;
button = factory->createButton();
assert(button != NULL);
delete scrollbar;
scrollbar = NULL;
scrollbar = factory->createScrollBar();
assert(scrollbar != NULL);
button->draw();
scrollbar->draw();
delete factory;
factory = NULL;
delete button;
button = NULL;
delete scrollbar;
scrollbar = NULL;
return 0;
}
运行结果:
优点:相比工厂方法模式,抽象工厂减少了类的数量,也便于统一管理相关的产品。
缺点:当需要增加一种产品的时候,就不符合开闭原则了。