forked from wenjy/design_patten_php
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Builder.php
164 lines (143 loc) · 3.36 KB
/
Builder.php
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
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
<?php
/**
* 建造者模式
*
* 将一个复杂的对象的结构与它的表示分离,使得同样的构建过程可以创建不同的表示,而不需要知道具体的建造过程
*
* 主要用于创建一些复杂的对象,这些对象内部构建的建造顺序通常是稳定的,但对象内部的构建通常面临复杂的变化。
*
* 建造者模式的好处就是使得建造代码与表示代码分离,由于建造者隐藏了该产品是如何组装的,
* 所以若需要改变一个产品的内部表示,只需要定义一个具体的建造者就可以了。
*
* 建造者模式是在当创建复杂对象的算法应该独立于该对象的组成部分以及它们的装配方式时适用的模式。
*
*/
/**
* 产品类,由多个部件组成
*
* Class Product
*/
class Product
{
/**
* @var array 保存所有的部件
*/
public $parts = [];
public function add($part)
{
$this->parts[] = $part;
}
/**
* 循环创建产品的所有部件
*
* @author jiangyi
*/
public function show()
{
echo '产品创建' . PHP_EOL;
foreach ($this->parts as $part) {
echo $part . PHP_EOL;
}
}
}
/**
* Builder 是为了创建一个 Product 对象的各个部分指定的抽象接口。
* 也就是 Product 的各个部件组成,和返回 Product
*
* Class Builder
*/
abstract class Builder
{
abstract public function buildPartA();
abstract public function buildPartB();
/**
* 这里不一定使用抽象方法,可以先实现
* @return mixed
* @author jiangyi
*/
abstract public function getResult();
}
/**
* 具体建造者,实现 Builder 接口,构造和装配各个部件
*
* Class ConcreteBuilder1
*/
class ConcreteBuilder1 extends Builder
{
/**
* 此属性可搬移至父类
* @var Product
*/
private $product;
/**
* ConcreteBuilder1 constructor.
*/
public function __construct()
{
$this->product = new Product();
}
public function buildPartA()
{
$this->product->add('部件A');
}
public function buildPartB()
{
$this->product->add('部件B');
}
public function getResult()
{
return $this->product;
}
}
class ConcreteBuilder2 extends Builder
{
private $product;
/**
* ConcreteBuilder2 constructor.
*/
public function __construct()
{
$this->product = new Product();
}
public function buildPartA()
{
$this->product->add('部件X');
}
public function buildPartB()
{
$this->product->add('部件Y');
}
public function getResult()
{
return $this->product;
}
}
/**
* 指挥者,构建一个使用 Builder 的对象
*
* Class Director
*/
class Director
{
/**
* 指挥者必须知道建造者的所有方法,然后调用具体的方法建造
*
* @param Builder $builder
* @author jiangyi
*/
public function construct(Builder $builder)
{
$builder->buildPartA();
$builder->buildPartB();
}
}
// 调用端不需要知道具体的建造过程
$director = new Director();
$b1 = new ConcreteBuilder1();
$b2 = new ConcreteBuilder2();
$director->construct($b1);
$p1 = $b1->getResult();
$p1->show();
$director->construct($b2);
$p2 = $b2->getResult();
$p2->show();