需求分析:
我们接到了一个订单,是宝马公司和奔驰公司的,他们负责定义产品的零部件以及型号,我们负责生产,需求简单的描述就是这样。 我们需要为这个需求设计一个设计模式去更好的适应他们的需求。
首先我们需要一个车模型类,来定义好需要的所有零部件,这就叫做抽象类,之所以这样是因为我们还有可能接到更多公司的订单,比如劳斯莱斯,宾利。
然后由各自的车来继承这个抽象类,实现里面的方法。
接下来就需要一个建造者抽象类,来定义建造各自的车需要的方法
然后由各自车建造者来继承这个抽象类。
我们会想到一个建造模式了,不错,就是建造者模式。用它简直太合适了。看一下建造者的用例图
请注意:此图示例方法部分和我的示例对不上哦。
直接上代码:
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开始建造,在上面的例子中就是我们的老大,牛叉公司找到老大,说我要这个,这个,那个类型的车辆模型,然后老大就把命令传递给我,我和我的团队就开始拼命的建造,于是一个项目建设完毕了。