简言之,就是业务逻辑需要创造一套套对应的组件。在不同条件下,需要的配套组件不同,但是这些组件都执行相似的功能。调用者直接接收一个工厂类,这个工厂类对应了一系列组件。不同的工厂制造不同的组件,但都遵循相同的接口。

换句话说,工厂实际上是对产品的一种打包!抽象工厂提供了对工厂的多态支持。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
class GUIFactory {
public:
virtual Button* createButton() const = 0;
virtual Checkbox* createCheckbox() const = 0;
};

class WinFactory: public GUIFactory {
public:
Button* createButton() const override {
return new WinButton();
}

Checkbox* createCheckbox() const override {
return new WinCheckbox();
}
};

class MacFactory: public GUIFactory {
public:
Button* createButton() const override {
return new MacButton();
}

Checkbox* createCheckbox() const override {
return new MacCheckbox();
}
};

class Button {
public:
virtual void paint() const = 0;
};

class WinButton: public Button {
public:
void paint() const override {
// render a windows button
}
};

class MacButton: public Button {
public:
void paint() const override {
// render a mac button
}
};

class Checkbox {
public:
virtual void paint() const = 0;
};

class WinCheckbox: public Checkbox {
public:
void paint() const override {
// render a windows button
}
};

class MacCheckbox: public Checkbox {
public:
void paint() const override {
// render a mac button
}
};

class Application {
private:
GUIFactory* factory;
Button* button;
public:
Application(GUIFactory* factory): factory(factory), button(nullptr) {}
~Application() {delete button;}
void createUI() {
delete button; // 避免重复创建button
button = factory->createButton();
}
void paint() {
button->paint();
}
}

class ApplicationConfigurator {
public:
GUIFactory* factory;
Application* app;
ApplicationConfigurator(): factory(nullptr), app(nullptr) {}
~ApplicationConfigurator() {
delete factory;
delete app;
}

void setup() {
Config config = readConfigFile();
if (config.OS == "Win") factory = new WinFactory;
else if (config.OS == "Mac") factory = new MacFactory;
else throw std::runtime_error("invalid config.OS");

app = new Application(factory);
}

void run() {
if (!app) setup();
app->createUI();
app->paint();
// other ui things...
}
}