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;
}
2011-07-19