無論是在現實世界中還是在軟體系統中,都存在一些複雜的物件,它們擁有多個組成部分。例如,我點了一杯奶茶,我只負責付錢,工作人員則給我一杯奶茶,在此期間我一般不會去關心放了多少奶,和其他的東西。畢竟不同的配方不同的口感也就代表了不同的價錢。
建造者模式(Builder Pattern): 將一個複雜物件的構建與它的表示分離,使得同樣的構建過程可以建立不同的表示。
建造者模式是一步一步建立一個複雜的物件,它允許使用者只通過指定複雜物件的型別和內容就可以構建它們,使用者不需要知道內部的具體構建細節。建造者模式屬於物件建立型模式。根據中文翻譯的不同,建造者模式又可以稱為生成器模式。
生成器模式結構圖
根據上面生成器模式結構圖 板栗:
// Beverages
// 抽象建造者:引入抽象建造者的目的,是為了將建造的具體過程交與它的子類來實現。
abstract class Builder
{
public $result;
abstract public function setWater();
abstract public function setMilk();
abstract public function setSugar();
public function __construct()
{
// $this->result = $res;
}
public function getMilkyTea(){
return $this->result;
}
}
// 建造者:實現抽象類的所有未實現的方法,組建產品、返回組建好的產品。
class ConcreteBuilder extends Builder
{
public function setWater()
{
$this->result['water']='50ml';
}
public function setMilk()
{
$this->result['milk']='25ml';
}
public function setSugar()
{
$this->result['sugar']='10g';
}
}
// 導演類:負責呼叫適當的建造者來組建產品
class Director
{
private $builder;
public function __construct(Builder $param)
{
$this->builder = $param;
}
public function build()
{
$this->builder->setWater();
$this->builder->setMilk();
$this->builder->setSugar();
}
}
$milkyTea = new ConcreteBuilder();
$director = new Director($milkyTea);
$director->build();
$result = $milkyTea->getMilkyTea();
print_r($result);
複製程式碼
這裡只是一個簡單的示例,大家可以修改一下,water、milk、sugar等改為其他值。或者是重寫這方法,可以建造出咖啡、奶茶、果奶等等。 意圖: 將一個複雜的構建與其表示相分離,使得同樣的構建過程可以建立不同的表示。
主要解決: 主要解決在軟體系統中,有時候面臨著"一個複雜物件"的建立工作,其通常由各個部分的子物件用一定的演算法構成;由於需求的變化,這個複雜物件的各個部分經常面臨著劇烈的變化,但是將它們組合在一起的演算法卻相對穩定。
何時使用: 一些基本部件不會變,而其組合經常變化的時候。
如何解決: 將變與不變分離開。
關鍵程式碼: 建造者:建立和提供例項,導演:管理建造出來的例項的依賴關係。
應用例項: 去肯德基,漢堡、可樂、薯條、炸雞翅等是不變的,而其組合是經常變化的,生成出所謂的"套餐"。
優點: 1、建造者獨立,易擴充套件。 2、便於控制細節風險。
缺點: 1、產品必須有共同點,範圍有限制。 2、如內部變化複雜,會有很多的建造類。
使用場景: 1、需要生成的物件具有複雜的內部結構。 2、需要生成的物件內部屬性本身相互依賴。
注意事項: 與工廠模式的區別是:建造者模式更加關注與零件裝配的順序。
寫於2018年5月28日,大家多多交流
參考資料: