Builder - 創建者模式
===
```=
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;
}
}
//老人建造者
class OlderBuider extends Builder{
public function setAge(){
$this->_person->age=70;
}
public function setSpeed(){
$this->_person->speed="low";
}
public function setKnowledge(){
$this->_person->knowledge='more';
}
}
//小孩建造者
class ChildBuider 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 OlderBuider(new Person);
//實例化一個建造指揮者
$director = new Director($oldB);
//指揮建造
$director->built();
//得到老人
$older = $oldB->getPerson();
```
### 使用建造者模式時,我們把創建一個person實例的過程分為了兩個步驟
一個步驟是先交給對應角色的建造者,如老人建造者。
這樣的好處就把角色的屬性設置封裝了起來,我們不用在new一個person時,因為要得到一個older角色的實例,而在外面寫了一堆$older->age=70。
另一個步驟是交給了一個建造指揮者,調了一個built方法,通過先設置age,再設置Speed的順序,初始化這個角色。
當然在這個例子中,初始化的順序,是無所謂的。但是如果對於一個建造漢堡,或是地圖,初始化的順序不同,可能就會得到不同的結果。
也許,你會說,我直接設置也很方便呀。是的,對於某些情況是這樣的。但是如果你考慮,我現在想增加一個青年人角色呢?如果我現在想讓建造有初始化有三種不同的順序呢?
如果你使用了建造者模式,這兩個問題就簡單了,增加一個青年人角色,那就增加一個青年建造者類。初始化三種不同的順序,那麼就在指揮建造者中增加兩種建造方法。
[PHP設計模式(三)—建造者模式(Builder Pattern)](https://www.jianshu.com/p/4af4a1d8201d)
Q&A
1. 如果增加一個條件:膚色?
>$this->_builder->setSkin();
>
>當如果Person的種類越來越多,要在每一個建造者下新增新的條件,將會變得很繁複。
2. 如果要建造一個速度快的老人?或不同年紀的老人?
>在差不多的條件下,是不是只能再增加新的建造者來符合需求?
###### tags: `DesignPattern`