wiki上的抽象工厂模式讲的蛮好的,尤其是例子选的很好。
抽象工厂模式(英语:Abstract Factory)是一种常见的设计模式。此模式为一个产品家族提供了统一的创建接口。当需要这个产品家族的某一系列的时候,可以从抽象工厂中选出相对系的系列来创建一个具体的工厂类别。
假设我们有两种产品接口 Button 和 Border ,每一种产品都支持多种系列,比如 Mac 系列和 Windows 系列。这样每个系列的产品分别是 MacButton, WinButton, MacBorder, WinBorder 。为了可以在运行时刻创建一个系列的产品族,我们可以为每个系列的产品族建立一个工厂 MacFactory 和 WinFactory 。每个工厂都有两个方法 CreateButton 和 CreateBorder 并返回对应的产品,可以将这两个方法抽象成一个接口 AbstractFactory 。这样在运行时刻我们可以选择创建需要的产品系列。
我们的产品结构是这样的
class Button; // Abstract Class class MacButton: public Button {}; class WinButton: public Button {}; class Border; // Abstract Class class MacBorder: public Border {}; class WinBorder: public Border {};
对应的工厂是这样的
class AbstractFactory { public: virtual Button* CreateButton() =0; virtual Border* CreateBorder() =0; }; class MacFactory: public AbstractFactory { public: MacButton* CreateButton() { return new MacButton; } MacBorder* CreateBorder() { return new MacBorder; } }; class WinFactory: public AbstractFactory { public: WinButton* CreateButton() { return new WinButton; } WinBorder* CreateBorder() { return new WinBorder; } };
那么客户可以根据需要选择 Mac 风格或者 Win 风格来创建 Button 或 Border
AbstractFactory* fac; switch (style) { case MAC: fac = new MacFactory; break; case WIN: fac = new WinFactory; break; } Button* button = fac->CreateButton(); Border* border = fac->CreateBorder();
适用性
在以下情况可以使用抽象工厂模式
优点
缺点
下面程序是在之上的基础上实现的
// Product.h #ifndef _PRODUCT_H_ #define _PRODUCT_H_ class Button { protected: Button(); public: virtual ~Button(); }; class Border { protected: Border(); public: virtual ~Border(); }; class MacButton : public Button { public: MacButton(); ~MacButton(); }; class WinButton : public Button { public: WinButton(); ~WinButton(); }; class MacBorder : public Border { public: MacBorder(); ~MacBorder(); }; class WinBorder : public Border { public: WinBorder(); ~WinBorder(); }; #endif // _PRODUCT_H_
// Product.cpp #include <iostream> using namespace std; #include "Product.h" ////////////////////Button///////////////////// Button::Button() { } Button::~Button() { } ///////////////////Border//////////////////////// Border::Border() { } Border::~Border() { } ////////////////////MacButton///////////////////// MacButton::MacButton() { cout << "MacButton::MacButton" << endl; } MacButton::~MacButton() { cout << "MacButton::~MacButton" << endl; } ///////////////////WinButton/////////////////////// WinButton::WinButton() { cout << "WinButton::WinButton" << endl; } WinButton::~WinButton() { cout << "WinButton::~WinButton" << endl; } ///////////////////MacBorder//////////////////////// MacBorder::MacBorder() { cout << "MacBorder::MacBorder" << endl; } MacBorder::~MacBorder() { cout << "MacBorder::~MacBorder" << endl; } ///////////////////WinBorder///////////////////////// WinBorder::WinBorder() { cout << "WinBorder::WinBorder" << endl; } WinBorder::~WinBorder() { cout << "WinBorder::~WinBorder" << endl; }
// Factory.h #ifndef _FACTORY_H_ #define _FACTORY_H_ class Button; class Border; class AbstractFactory { public: virtual Button* CreateButton() = 0; virtual Border* CreateBorder() = 0; virtual ~AbstractFactory(); protected: AbstractFactory(); }; class MacFactory : public AbstractFactory { public: MacFactory(); ~MacFactory(); Button* CreateButton(); Border* CreateBorder(); }; class WinFactory : public AbstractFactory { public: WinFactory(); ~WinFactory(); Button* CreateButton(); Border* CreateBorder(); }; #endif // _FACTORY_H_
// Factory.cpp #include <iostream> using namespace std; #include "Factory.h" #include "Product.h" AbstractFactory::AbstractFactory() { } AbstractFactory::~AbstractFactory() { } ///////////////////////////////////////// MacFactory::MacFactory() { cout << "MacFactory::MacFactory" << endl; } MacFactory::~MacFactory() { cout << "MacFactory::~MacFactory" << endl; } Button* MacFactory::CreateButton() { return new MacButton(); } Border* MacFactory::CreateBorder() { return new MacBorder(); } /////////////////////////////////////////// WinFactory::WinFactory() { cout << "WinFactory::WinFactory" << endl; } WinFactory::~WinFactory() { cout << "WinFactory::~WinFactory" << endl; } Button* WinFactory::CreateButton() { return new WinButton(); } Border* WinFactory::CreateBorder() { return new WinBorder(); }
// main.cpp #include <iostream> #include "Product.h" #include "Factory.h" using namespace std; #define MAC 1 #define WIN 2 int main(int argc, char *argv[]) { AbstractFactory *fac = NULL; int style = 0; cout << "input factory style(MAC:1, WIN:2)" << endl; cin >> style; switch (style) { case MAC: fac = new MacFactory(); break; case WIN: fac = new WinFactory(); break; default: cout << "no this style" << endl; goto END; } Button* button = fac->CreateButton(); Border* border = fac->CreateBorder(); END: system("pause"); return 0; }