PHP設計模式(三)——建造者模式(Builder Pattern)
@[TOC](PHP設計模式(三)——建造者模式(Builder Pattern))
建造者模式(Builder Pattern):將一個複雜物件的構建與它的表示分離,使得同樣的構建過程可以建立不同的表示。
建造者模式是一步一步建立一個複雜的物件,它允許使用者只通過指定複雜物件的型別和內容就可以構建它們,使用者不需要知道內部的具體構建細節。建造者模式屬於物件建立型模式。根據中文翻譯的不同,建造者模式又可以稱為生成器模式。
(一)為什麼需要建造者模式
1,物件的生產需要複雜的初始化,比如給一大堆類成員屬性賦初值,設定一下其他的系統環境變數。使用建造者模式可以將這些初始化工作封裝起來。
2,物件的生成時可根據初始化的順序或資料不同,而生成不同角色。
(二)模式應用
在很多遊戲軟體中,地圖包括天空、地面、背景等組成部分,人物角色包括人體、服裝、裝備等組成部分,可以使用建造者模式對其進行設計,通過不同的具體建造者建立不同型別的地圖或人物
(三)設計例項
如果我們想創造出有一個person類,我們通過例項化時設定的屬性不同,讓他們兩人一個是速度快的小孩,一個是知識深的長者
<?php // 建造者資訊規格 (擺件規格資訊) class person { public $age; public $speed; public $knowledge; } // 抽象建造者類(擺件造模) abstract class Builder { public $_person; public abstract function setAge(); public abstract function setSpeed(); public abstract function setKnowledge(); public function __construct(Person $person) { $this->_person = $person; } public function getPerson() { return $this->_person; } } // 長者建造者 (擺件1規格) class OlderBuilder extends Builder { public function setAge() { $this->_person->age = 70; } public function setSpeed() { $this->_person->speed = 'low'; } public function setKnowledge() { $this->_person->knowledge = 'more'; } } // 長者建造者(擺件2規格) class ChildBuilder extends Builder { public function setAge() { $this->_person->age = 10; } public function setSpeed() { $this->_person->speed = 'fast'; } public function setKnowledge() { $this->_person->knowledge = 'litte'; } } // 建築指揮官 (造擺件的人) class Director { private $_builder; public function __construct(Builder $builder) { $this->_builder = $builder; } public function built() { $this->_builder->setAge(); $this->_builder->setSpeed(); $this->_builder->setKnowledge(); } } // 例項化 長者建造者 $oldB = new OlderBuilder(new Person); // 例項化一個建造指揮官 $director = new Director($oldB); // 指揮官建造 $director->built(); // 得到長者 $older = $oldB->getPerson(); var_dump($older);
(五)總結
使用建造者模式時,我們把建立一個person例項的過程分為了兩步.
一步是先交給對應角色的建造者,如長者建造者。這樣的好處就把角色的屬性設定封裝了起來,我們不用在new一個person時,因為要得到一個older角色的例項,而在外面寫了一堆$older->age=70。
另一步是交給了一個建造指揮者,調了一個built方法,通過先設定age,再設定Speed的順序,初始化這個角色。當然在這個例子中,初始化的順序,是無所謂的。但是如果對於一個建造漢堡,或是地圖,初始化的順序不同,可能就會得到不同的結果。
也許,你會說,我直接設定也很方便呀。是的,對於某些情況是這樣的。但是如果你考慮,我現在想增加一個青年人角色呢?如果我現在想讓建造有初始化有三種不同的順序呢?
如果你使用了建造者模式,這兩個問題就簡單了,增加一個青年人角色,那就增加一個青年年建造者類。初始化三種不同的順序,那麼就在指揮建造者中增加兩種建造方法。