设计模式之Builder模式

将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示。

设计原则:

  1. 不会变化的是创建两个方法,变化的是怎么创建,于是抽取基类和两个创建方法
  2. 聚合了会发生变化的基类

实现

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
109
110
111
112
113
#include <iostream>
#include <string>

// Product class
class Pizza {
public:
void setDough(const std::string& dough) {
m_dough = dough;
}
void setSauce(const std::string& sauce) {
m_sauce = sauce;
}
void setTopping(const std::string& topping) {
m_topping = topping;
}
void open() const {
std::cout << "Pizza with " << m_dough << " dough, " << m_sauce << " sauce and " << m_topping << " topping. Bon appétit!" << std::endl;
}

private:
std::string m_dough;
std::string m_sauce;
std::string m_topping;
};

// Abstract builder class
class PizzaBuilder {
public:
virtual ~PizzaBuilder() {}
Pizza* getPizza() {
return m_pizza;
}
void createNewPizzaProduct() {
m_pizza = new Pizza();
}
virtual void buildDough() = 0;
virtual void buildSauce() = 0;
virtual void buildTopping() = 0;

protected:
Pizza* m_pizza;
};

// Concrete builder classes
class HawaiianPizzaBuilder : public PizzaBuilder {
public:
void buildDough() {
m_pizza->setDough("cross");
}
void buildSauce() {
m_pizza->setSauce("mild");
}
void buildTopping() {
m_pizza->setTopping("ham+pineapple");
}
};

class SpicyPizzaBuilder : public PizzaBuilder {
public:
void buildDough() {
m_pizza->setDough("pan baked");
}
void buildSauce() {
m_pizza->setSauce("hot");
}
void buildTopping() {
m_pizza->setTopping("pepperoni+salami");
}
};

// Director class
class Cook {
public:
void setPizzaBuilder(PizzaBuilder* builder) {
m_pizzaBuilder = builder;
}
Pizza* getPizza() {
return m_pizzaBuilder->getPizza();
}
void constructPizza() {
m_pizzaBuilder->createNewPizzaProduct();
m_pizzaBuilder->buildDough();
m_pizzaBuilder->buildSauce();
m_pizzaBuilder->buildTopping();
}

private:
PizzaBuilder* m_pizzaBuilder;
};

// Client code
int main() {
Cook cook;
PizzaBuilder* hawaiianPizzaBuilder = new HawaiianPizzaBuilder();
PizzaBuilder* spicyPizzaBuilder = new SpicyPizzaBuilder();

cook.setPizzaBuilder(hawaiianPizzaBuilder);
cook.constructPizza();
Pizza* hawaiianPizza = cook.getPizza();
hawaiianPizza->open();

cook.setPizzaBuilder(spicyPizzaBuilder);
cook.constructPizza();
Pizza* spicyPizza = cook.getPizza();
spicyPizza->open();

delete hawaiianPizzaBuilder;
delete spicyPizzaBuilder;
delete hawaiianPizza;
delete spicyPizza;

return 0;
}

这个示例中,我们有一个Pizza类作为产品,它有几个属性(面团、酱料和配料)。然后,我们定义了一个抽象的PizzaBuilder类,它有一些纯虚函数来构建产品的不同部分。然后,我们有两个具体的建造者类HawaiianPizzaBuilderSpicyPizzaBuilder,它们实现了抽象建造者类的纯虚函数。最后,我们有一个Cook类作为指导者,它负责使用特定的建造者来构建产品。

main函数中,我们创建了一个Cook对象,并使用HawaiianPizzaBuilder来构建夏威夷披萨,然后使用SpicyPizzaBuilder来构建辣披萨。最后,我们打开这两个披萨。