需求分析:
我們接到了一個訂單,是寶馬公司和奔馳公司的,他們負責定義產品的零部件以及型號,我們負責生產,需求簡單的描述就是這樣。 我們需要為這個需求設計一個設計模式去更好的適應他們的需求。
首先我們需要一個車模型類,來定義好需要的所有零部件,這就叫做抽象類,之所以這樣是因為我們還有可能接到更多公司的訂單,比如勞斯萊斯,賓利。
然後由各自的車來繼承這個抽象類,實現裡面的方法。
接下來就需要一個建造者抽象類,來定義建造各自的車需要的方法
然後由各自車建造者來繼承這個抽象類。
我們會想到一個建造模式了,不錯,就是建造者模式。用它簡直太合適了。看一下建造者的用例圖

請注意:此圖示例方法部分和我的示例對不上哦。
直接上代碼:
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. 將一個復雜對象的構建與它的表示分離,使得同樣的構建過程可以創建不同的表示。
建造者模式的通用類圖如圖所示。

在建造者模式中,有如下四個角色:
通常是實現了模板方法模式,也就是有模板方法和基本方法,這個參考上一章節的模板方法模式。在例子中,BenzModel和BMWModel就屬於產品類。
規范產品的組建,一般是由子類實現。在例子中,CarBuilder屬於抽象建造者。
實現抽象類定義的所有方法,並且返回一個組件好的對象。在例子中,BenzBuilder和BMWBuilder就屬於具體建造者。
負責安排已有模塊的順序,然後告訴Builder開始建造,在上面的例子中就是我們的老大,牛叉公司找到老大,說我要這個,這個,那個類型的車輛模型,然後老大就把命令傳遞給我,我和我的團隊就開始拼命的建造,於是一個項目建設完畢了。
你不必特別去找'php設計模式',你可以找找‘設計模式’or‘java設計模式’之類的比較好找。因為設計模式並不是針對某個語言而是一種思想,所以你無論是看'php設計模式'or‘java設計模式’or‘設計模式’得到的設計思想都是一樣的
如果使用UserFactory,你就不用知道有User類的存在,抽象類幫你隱藏它,以後要是類多了,該模式維護起來就比較方便,建議你去了解抽象工廠模式,工廠模式,工廠方法模式,這些都是為了可復用編程的手段。