php设计模式 — 建造者模式
我们接到了一个订单,是宝马公司和奔驰公司的,他们负责定义产品的零部件以及型号,我们负责生产,需求简单的描述就是这样。 我们需要为这个需求设计一个设计模式去更好的适应他们的需求。
首先我们需要一个车模型类,来定义好需要的所有零部件,这就叫做抽象类,之所以这样是因为我们还有可能接到更多公司的订单,比如劳斯莱斯,宾利。
然后由各自的车来继承这个抽象类,实现里面的方法。
接下来就需要一个建造者抽象类,来定义建造各自的车需要的方法
然后由各自车建造者来继承这个抽象类。
我们会想到一个建造模式了,不错,就是建造者模式。用它简直太合适了。看一下建造者的用例图
请注意:此图示例方法部分和我的示例对不上哦。
直接上代码:
复制代码
1 <?php
2
3 abstract class carModel{
4
5 //这里存储所有组装车需要的零件
6 public $spareParts = array();
7
8 //车的名字
9 public $carName = "";
10
11 //增加*部件
12 public abstract function addLunzi($xinghao);
13
14 //增加外壳部件
15 public abstract function addWaike($xinghao);
16
17 //增加发动机部件
18 public abstract function addFadongji($xinghao);
19
20 //获取车,并给车取名字
21 final public function getCar($carName){
22 if($this->spareParts){
23 $this->carName = $carName;
24 //$k 代表部件名字
25 //$v 代表型号
26 foreach($this->spareParts as $k=>$v){
27 $actionName = "add" . $k;
28 $this->$actionName($v);
29 }
30 }else{
31 throw new Exception("没有汽车部件");
32
33 }
34 }
35 }
36
37
38 //定义具体的产品
39 class bmwCarModel extends carModel{
40
41 public $spareParts = array();
42 public $carName = "";
43
44 public function addLunzi($xinghao){
45 echo "宝马".$this->carName."的*,型号是" . $xinghao . "\n";
46 }
47
48 public function addWaike($xinghao){
49 echo "宝马".$this->carName."的外壳,型号是" . $xinghao . "\n";
50 }
51
52 public function addFadongji($xinghao){
53 echo "宝马".$this->carName."的发动机,型号是 " . $xinghao . "\n";
54 }
55 }
56
57
58 //定义具体的产品
59 class benziCarModel extends carModel{
60
61 public $spareParts = array();
62 public $carName = "";
63
64 public function addLunzi($xinghao){
65 echo "奔驰".$this->carName."的*,型号是" . $xinghao . "\n";
66 }
67
68 public function addWaike($xinghao){
69 echo "奔驰".$this->carName."的外壳,型号是" . $xinghao . "\n";
70 }
71
72 public function addFadongji($xinghao){
73 echo "奔驰".$this->carName."的发动机,型号是 " . $xinghao . "\n";
74 }
75 }
76
77
78
79 //定义建造者
80 abstract class carBuilder{
81 public abstract function setSpareParts($partsName , $xinghao);
82
83 public abstract function getCarModel($name);
84 }
85
86
87 class bmwBuilder extends carBuilder{
88 private $bmwModel;
89
90 public function __construct(){
91 $this->bmwModel = new bmwCarModel();
92 }
93
94 public function setSpareParts($partsName , $xinghao){
95 $this->bmwModel->spareParts[$partsName] = $xinghao;
96 }
97
98 public function getCarModel($name){
99 $this->bmwModel->getCar($name);
100 }
101 }
102
103
104 class benziBuilder extends carBuilder{
105 private $benziModel;
106
107 public function __construct(){
108 $this->benziModel = new benziCarModel();
109 }
110
111 public function setSpareParts($partsName , $xinghao){
112 $this->bmwModel->spareParts[$partsName] = $xinghao;
113 }
114
115 public function getCarModel($name){
116 $this->bmwModel->getCar($name);
117 }
118 }
119
120
121
122 //模拟客户端调用
123
124 //创建一辆宝马车,取名字为宝马x1
125
126 $bmwBuilder = new bmwBuilder();
127 $bmwBuilder->setSpareParts('Lunzi' , '牛逼*1号');
128 $bmwBuilder->setSpareParts('Waike' , '牛逼外壳1号');
129 $bmwBuilder->setSpareParts('Fadongji' , '牛逼发动机1号');
130 $bmwBuilder->getCarModel("宝马x1");
131 $bmwBuilder->getCarModel("宝马x1"); //连续创建两个宝马x1
132
133 //再创建一个宝马 没有外壳 取名为 宝马s5
134 $bmwBuilder = new bmwBuilder();
135 $bmwBuilder->setSpareParts('Lunzi' , '牛逼*2号');
136 $bmwBuilder->setSpareParts('Fadongji' , '牛逼发动机2号');
137 $bmwBuilder->getCarModel("宝马s5");
138 $bmwBuilder->getCarModel("宝马s5"); //连续创建两个宝马x1
复制代码
代码可以直接运行,你可以试着去生产一辆牛逼的奔驰车哦。
建造者模式的定义
建造者模式(Builder Pattern)也叫做生成器模式,其定义如下:
Separate the construction of a complex object from its representation so that the same construction process can create different representations. 将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示。
建造者模式的通用类图如图所示。
clip_image008
在建造者模式中,有如下四个角色:
Product 产品类
通常是实现了模板方法模式,也就是有模板方法和基本方法,这个参考上一章节的模板方法模式。在例子中,BenzModel和BMWModel就属于产品类。
Builder 抽象建造者
规范产品的组建,一般是由子类实现。在例子中,CarBuilder属于抽象建造者。
ConcreteBuilder 具体建造者
实现抽象类定义的所有方法,并且返回一个组件好的对象。在例子中,BenzBuilder和BMWBuilder就属于具体建造者。
Director 导演
负责安排已有模块的顺序,然后告诉Builder开始建造,在上面的例子中就是我们的老大,牛叉公司找到老大,说我要这个,这个,那个类型的车辆模型,然后老大就把命令传递给我,我和我的团队就开始拼命的建造,于是一个项目建设完毕了。
下一篇: ps中怎么设计绿色的对话框?