需求分析:
我們接到了一個訂單,是寶馬公司和奔馳公司的,他們負責定義產品的零部件以及型號,我們負責生產,需求簡單的描述就是這樣。 我們需要為這個需求設計一個設計模式去更好的適應他們的需求。
首先我們需要一個車模型類,來定義好需要的所有零部件,這就叫做抽象類,之所以這樣是因為我們還有可能接到更多公司的訂單,比如勞斯萊斯,賓利。
然後由各自的車來繼承這個抽象類,實現裡面的方法。
接下來就需要一個建造者抽象類,來定義建造各自的車需要的方法
然後由各自車建造者來繼承這個抽象類。
我們會想到一個建造模式了,不錯,就是建造者模式。用它簡直太合適了。看一下建造者的用例圖
請注意:此圖示例方法部分和我的示例對不上哦。
直接上代碼:
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類的存在,抽象類幫你隱藏它,以後要是類多了,該模式維護起來就比較方便,建議你去了解抽象工廠模式,工廠模式,工廠方法模式,這些都是為了可復用編程的手段。