设计模式之建造者模式

建造者模式

概念

  • 将复杂对象的构造和表示分开,是的同样的步骤可以创建不同的表示(对象)
  • 解析一个复杂的表示(对象),封装对象的构造过程。(将建造复杂对下岗的过程和组成对象的不见解耦)

UML图

建造者模式

director在接收到请求时调用构建服务,构建器每一次调用时都会一步步的创建
(buildPartA(),buildPartB(),buildPartC())一个复杂对象,产品构建完成后,
客户端通过方法(getResult())获取实例。

应用场景

  • 需要生成的产品对象有复杂的内部结构,这些产品对象具备共性;
  • 隔离复杂对象的创建和使用,并使得相同的创建过程可以创建不同的产品。

优缺点

优点

  • 易于解耦
    将产品本身与产品的创建过程进行解耦,可以使用相同的创建过程来得到不同的产品,细节依赖抽象

  • 易于控制对象的创建
    将复杂产品的创建步骤分解,使创建过程更加清晰

  • 扩展性好(易于扩展)
    增加新的具体建造者(Builder)无需修改原来类库的代码,易于扩展,符合”开闭原则”

1
2
每一个具体建造者都相对独立,而与其他的具体建造者无关,因此可以很方便地替换具体建造者或
增加新的具体建造者,用户使用不同的具体建造者即可得到不同的产品对象。

缺点

  • 建造者模式所创建的产品一般具有较多的共同点,其组成部分相似;如果产品之间的差异性很大,
    则不适合使用建造者模式,因此其使用范围受到一定的限制。

  • 如果产品的内部变化复杂,可能会导致需要定义很多具体建造者类来实现这种变化,
    导致系统变得很庞大。

例子

现实例子

将复杂对象的构造和表示分开,是的同样的步骤可以创建不同的表示(对象),上面这个模型是快餐
店用来制作儿童套餐的,儿童套餐由主食、副食、饮料和玩具这几部分组成。
请注意,儿童套餐的内容可能不同,但是制作过程是相同的,无论客户订购汉堡包或是芝士汉堡
还是鸡肉,流程都是相同的。柜台的员工(director)组装主要物品,辅助物品和玩具,然后将这
些放在一个袋子中,饮料放在另一个袋子里面,这就是一个典型的建造者模式(Builder mode)

示例代码

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
/* "Product" */
class Pizza {
private String dough = "";
private String sauce = "";
private String topping = "";

public void setDough(String dough) {
this.dough = dough;
}

public void setSauce(String sauce) {
this.sauce = sauce;
}

public void setTopping(String topping) {
this.topping = topping;
}
}

/* "Abstract Builder" */
abstract class PizzaBuilder {
protected Pizza pizza;

public Pizza getPizza() {
return pizza;
}

public void createNewPizzaProduct() {
pizza = new Pizza();
}

public abstract void buildDough();
public abstract void buildSauce();
public abstract void buildTopping();
}

/* "ConcreteBuilder" */
class HawaiianPizzaBuilder extends PizzaBuilder {
public void buildDough() {
pizza.setDough("cross");
}

public void buildSauce() {
pizza.setSauce("mild");
}

public void buildTopping() {
pizza.setTopping("ham+pineapple");
}
}

/* "ConcreteBuilder" */
class SpicyPizzaBuilder extends PizzaBuilder {
public void buildDough() {
pizza.setDough("pan baked");
}

public void buildSauce() {
pizza.setSauce("hot");
}

public void buildTopping() {
pizza.setTopping("pepperoni+salami");
}
}

/* "Director" */
class Waiter {
private PizzaBuilder pizzaBuilder;

public void setPizzaBuilder(PizzaBuilder pb) {
pizzaBuilder = pb;
}

public Pizza getPizza() {
return pizzaBuilder.getPizza();
}

public void constructPizza() {
pizzaBuilder.createNewPizzaProduct();
pizzaBuilder.buildDough();
pizzaBuilder.buildSauce();
pizzaBuilder.buildTopping();
}
}

/* A customer ordering a pizza. */
public class PizzaBuilderDemo {
public static void main(String[] args) {
Waiter waiter = new Waiter();
PizzaBuilder hawaiianPizzabuilder = new HawaiianPizzaBuilder();
PizzaBuilder spicyPizzaBuilder = new SpicyPizzaBuilder();

waiter.setPizzaBuilder( hawaiianPizzabuilder );
waiter.constructPizza();

Pizza pizza = waiter.getPizza();
}
}