第七節 PHP設計模式(六)—建造者模式(Builder Pattern)

建造者模式(Builder Pattern):將一個複雜對象的構建與它的表示分離,使得同樣的構建過程可以創建不同的表示。

建造者模式是一步一步創建一個複雜的對象,它允許用戶只通過指定複雜對象的類型和內容就可以構建它們,用戶不需要知道內部的具體構建細節。建造者模式屬於對象創建型模式。根據中文翻譯的不同,建造者模式又可以稱爲生成器模式。

(一)爲什麼需要建造者模式
1,對象的生產需要複雜的初始化,比如給一大堆類成員屬性賦初值,設置一下其他的系統環境變量。使用建造者模式可以將這些初始化工作封裝起來。
2,對象的生成時可根據初始化的順序或數據不同,而生成不同角色。

優點:

  • 在建造者模式中, 客戶端不必知道產品內部組成的細節,將產品本身與產品的創建過程解耦,使得相同的創建過程可以創建不同的產品對象。
  • 每一個具體建造者都相對獨立,而與其他的具體建造者無關,因此可以很方便地替換具體建造者或增加新的具體建造者, 用戶使用不同的具體建造者即可得到不同的產品對象 。
  • 可以更加精細地控制產品的創建過程 。將複雜產品的創建步驟分解在不同的方法中,使得創建過程更加清晰,也更方便使用程序來控制創建過程。
  • 增加新的具體建造者無須修改原有類庫的代碼,指揮者類針對抽象建造者類編程,系統擴展方便,符合“開閉原則”。

缺點:

  • 建造者模式所創建的產品一般具有較多的共同點,其組成部分相似,如果產品之間的差異性很大,則不適合使用建造者模式,因此其使用範圍受到一定的限制。
  • 如果產品的內部變化複雜,可能會導致需要定義很多具體建造者類來實現這種變化,導致系統變得很龐大。

 (二)模式應用
在很多遊戲軟件中,地圖包括天空、地面、背景等組成部分,人物角色包括人體、服裝、裝備等組成部分,可以使用建造者模式對其進行設計,通過不同的具體建造者創建不同類型的地圖或人物

(三)設計實例


class Person{
    public $age;
    public $spend;
    public $knowledge;
}

abstract class Builder{
    public $_preson;
    abstract public function setAge();
    abstract public function setSpend();
    abstract public function setKnowledge();
    public function __construct($person)
    {
        $this->_preson = $person;
    }
    public function getPerson(){
        return $this->_preson;
    }
}
class OlderBuilder extends Builder {
    public function setAge()
    {
        $this->_preson->age = 70;
    }
    public function setSpend()
    {
        $this->_preson->spend = "low";
    }

    public function setKnowledge()
    {
        $this->_preson->knowledge = "more";
    }
}

class ChildBuilder extends Builder {
    public function setAge()
    {
        $this->_preson->age = 10;
    }
    public function setSpend()
    {
        $this->_preson->spend = "fast";
    }

    public function setKnowledge()
    {
        $this->_preson->knowledge = "litte";
    }
}

class Director{
    private $_builder;

    public function __construct(Builder $builder)
    {
        $this->_builder = $builder;
    }

    public function built()
    {
        $this->_builder->setAge();
        $this->_builder->setSpend();
        $this->_builder->setKnowledge();
    }
}

$old = new ChildBuilder(new Person());
$director = new Director($old);
$director->built();

$older = $old->getPerson();
var_dump($older);

(四)總結

  • 在建造者模式中, 客戶端不必知道產品內部組成的細節,將產品本身與產品的創建過程解耦,使得相同的創建過程可以創建不同的產品對象。
  • 每一個具體建造者都相對獨立,而與其他的具體建造者無關,因此可以很方便地替換具體建造者或增加新的具體建造者, 用戶使用不同的具體建造者即可得到不同的產品對象 。
  • 可以更加精細地控制產品的創建過程 。將複雜產品的創建步驟分解在不同的方法中,使得創建過程更加清晰,也更方便使用程序來控制創建過程。
  • 增加新的具體建造者無須修改原有類庫的代碼,指揮者類針對抽象建造者類編程,系統擴展方便,符合“開閉原則”
     
  • 建造者模式所創建的產品一般具有較多的共同點,其組成部分相似,如果產品之間的差異性很大,則不適合使用建造者模式,因此其使用範圍受到一定的限制。
  • 如果產品的內部變化複雜,可能會導致需要定義很多具體建造者類來實現這種變化,導致系統變得很龐大。
  • 建造者模式將一個複雜對象的構建與它的表示分離,使得同樣的構建過程可以創建不同的表示。建造者模式是一步一步創建一個複雜的對象,它允許用戶只通過指定複雜對象的類型和內容就可以構建它們,用戶不需要知道內部的具體構建細節。建造者模式屬於對象創建型模式。
  • 建造者模式包含如下四個角色:抽象建造者爲創建一個產品對象的各個部件指定抽象接口;具體建造者實現了抽象建造者接口,實現各個部件的構造和裝配方法,定義並明確它所創建的複雜對象,也可以提供一個方法返回創建好的複雜產品對象;產品角色是被構建的複雜對象,包含多個組成部件;指揮者負責安排複雜對象的建造次序,指揮者與抽象建造者之間存在關聯關係,可以在其construct()建造方法中調用建造者對象的部件構造與裝配方法,完成複雜對象的建造
  • 在建造者模式的結構中引入了一個指揮者類,該類的作用主要有兩個:一方面它隔離了客戶與生產過程;另一方面它負責控制產品的生成過程。指揮者針對抽象建造者編程,客戶端只需要知道具體建造者的類型,即可通過指揮者類調用建造者的相關方法,返回一個完整的產品對象。
  • 建造者模式的主要優點在於客戶端不必知道產品內部組成的細節,將產品本身與產品的創建過程解耦,使得相同的創建過程可以創建不同的產品對象,每一個具體建造者都相對獨立,而與其他的具體建造者無關,因此可以很方便地替換具體建造者或增加新的具體建造者,符合“開閉原則”,還可以更加精細地控制產品的創建過程;其主要缺點在於由於建造者模式所創建的產品一般具有較多的共同點,其組成部分相似,因此其使用範圍受到一定的限制,如果產品的內部變化複雜,可能會導致需要定義很多具體建造者類來實現這種變化,導致系統變得很龐大。
  • 建造者模式適用情況包括:需要生成的產品對象有複雜的內部結構,這些產品對象通常包含多個成員屬性;需要生成的產品對象的屬性相互依賴,需要指定其生成順序;對象的創建過程獨立於創建該對象的類;隔離複雜對象的創建和使用,並使得相同的創建過程可以創建不同類型的產品。

參考資料:

https://design-patterns.readthedocs.io

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章