---
# System prepended metadata

title: Builder - 創建者模式
tags: [DesignPattern]

---

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`