建造者模式,也能夠叫作生成器模式,builder這個詞的原意就包含了建築者、開發者、建立者的含義。很明顯,這個模式又是一個建立型的模式,用來建立對象。那麼它的特色是什麼呢?從建築上來講,蓋房子不是一會兒就立刻能把一個房子蓋好的,而是經過一磚一瓦搭建出來的。一個房子不只有磚瓦,還有各類管道,各類電線等等,由它們各個不部分共同組成了一棟房子。能夠說,建造者模式就是這樣很是形象的由各類部件來組成一個對象(房子)的過程。php
GoF定義:將一個複雜對象的構建與它的表示分離,使得一樣的構建過程能夠建立不一樣的表示git
GoF類圖github
代碼實現數據庫
class Product {
private $parts = [];
public function Add(String $part): void {
$this->parts[] = $part;
}
public function Show(): void {
echo PHP_EOL . '產品建立 ----', PHP_EOL;
foreach ($this->parts as $part) {
echo $part, PHP_EOL;
}
}
}
複製代碼
產品類,你能夠把它想象成咱們要建造的房子。這時的房子尚未任何內容,咱們須要給它添磚加瓦。設計模式
interface Builder {
public function BuildPartA(): void;
public function BuildPartB(): void;
public function GetResult(): Product;
}
class ConcreteBuilder1 implements Builder {
private $product;
public function __construct() {
$this->product = new Product();
}
public function BuildPartA(): void {
$this->product->Add('部件A');
}
public function BuildPartB(): void {
$this->product->Add('部件B');
}
public function GetResult(): Product {
return $this->product;
}
}
class ConcreteBuilder2 implements Builder {
private $product;
public function __construct() {
$this->product = new Product();
}
public function BuildPartA(): void {
$this->product->Add('部件X');
}
public function BuildPartB(): void {
$this->product->Add('部件Y');
}
public function GetResult(): Product {
return $this->product;
}
}
複製代碼
建造者抽象及其實現。不一樣的開發商總會選用不一樣的品牌材料,這裏咱們有了兩個不一樣的開發商,但他們的目的一致,都是爲了去蓋房子(Product)。架構
class Director {
public function Construct(Builder $builder) {
$builder->BuildPartA();
$builder->BuildPartB();
}
}
複製代碼
構造器,用來調用建造者進行生產。沒錯,就是咱們的工程隊。它來選取材料並進行建造。一樣的工程隊,能夠接不一樣的單,但蓋出來的都是房子。只是這個房子的材料和外觀不一樣,大致上的手藝仍是共通的。框架
$director = new Director();
$b1 = new ConcreteBuilder1();
$b2 = new ConcreteBuilder2();
$director->Construct($b1);
$p1 = $b1->getResult();
$p1->Show();
$director->Construct($b2);
$p2 = $b2->getResult();
$p2->Show();
複製代碼
最後看看咱們的實現,是否是很是簡單,準備好工程隊,準備好不一樣的建造者,而後交給工程隊去生產就好啦!!ui
你們都知道,手機組裝是一件複雜的過程,因而,不一樣型號的手機咱們都有對應的圖紙(Builder),將圖紙和配件交給流水線上的工人(Director),他們就會根據圖紙使用配件來生產出咱們所須要的各類不一樣型號的手機(Product)。很明顯,咱們都是偉大的建造者,爲咱們的產業添磚加瓦!!!this
完整代碼:github.com/zhangyue050…spa
前面說過Android中有不少Dialog對話框都會用建造者模式來實現,做爲一家手機廠的老闆,定製化的Android系統也是很是重要的一個部分。就像X米同樣,從MIUI入手,先拿下了軟件市場,讓你們以爲這個系統很是好用,而後再開始開發手機。這就說明軟硬件的確是現代手機的兩大最重要的組成部分,缺了誰都不行。這回,咱們就用建造者模式簡單的實現一套對話框組件吧!
對話框類圖
<?php
class Dialog {
private $attributes = [];
private $buttons = [];
private $title = '';
private $content = '';
public function AddAttributes($attr) {
$this->attributes[] = $attr;
}
public function AddButtons($button) {
$this->buttons[] = $button;
}
public function SetTitle($title) {
$this->title = $title;
}
public function SetContent($content) {
$this->content = $content;
}
public function ShowDialog(){
echo PHP_EOL, '顯示提示框 === ', PHP_EOL;
echo '標題:' . $this->title, PHP_EOL;
echo '內容:' . $this->content, PHP_EOL;
echo '樣式:' . implode(',', $this->attributes), PHP_EOL;
echo '按扭:' . implode(',', $this->buttons), PHP_EOL;
}
}
interface Builder {
public function BuildAttribute($attr);
public function BuildButton($button);
public function BuildTitle($title);
public function BuildContent($content);
public function GetDialog();
}
class DialogBuilder implements Builder{
private $dialog;
public function __construct(){
$this->dialog = new Dialog();
}
public function BuildAttribute($attr){
$this->dialog->AddAttributes($attr);
}
public function BuildButton($button){
$this->dialog->AddButtons($button);
}
public function BuildTitle($title){
$this->dialog->SetTitle($title);
}
public function BuildContent($content){
$this->dialog->SetContent($content);
}
public function GetDialog(){
return $this->dialog;
}
}
class DialogDirector {
public function Construct($title, $content){
$builder = new DialogBuilder();
$builder->BuildAttribute('置於頂層');
$builder->BuildAttribute('居中顯示');
$builder->BuildButton('確認');
$builder->BuildButton('取消');
$builder->BuildTitle($title);
$builder->BuildContent($content);
return $builder;
}
}
class ModalDialogDirector {
public function Construct($title, $content){
$builder = new DialogBuilder();
$builder->BuildAttribute('置於頂層');
$builder->BuildAttribute('居中顯示');
$builder->BuildAttribute('背景庶照');
$builder->BuildAttribute('外部沒法點擊');
$builder->BuildButton('確認');
$builder->BuildButton('取消');
$builder->BuildTitle($title);
$builder->BuildContent($content);
return $builder;
}
}
$d1 = new DialogDirector();
$d1->Construct('窗口1', '確認要執行操做A嗎?')->GetDialog()->ShowDialog();
$d2 = new ModalDialogDirector();
$d2->Construct('窗口2', '確認要執行操做B嗎?')->GetDialog()->ShowDialog();
複製代碼
說明
建造者模式真的很是經常使用,雖然說咱們日常寫的代碼中可能用得比較少,但在不少框架或者大型系統的架構中都會有它的身影。咱們但願類都是簡單的,小巧的,但大型類的出現老是不可避免的,這個時候,建造者模式就能發揮它的做用,讓咱們可以輕鬆的構建複雜、大型的對象。好吧,不要忘了咱們的文章還在繼續,若是喜歡的話要記得關注公衆號或者掘金主頁哦,若是怕忘了,不妨寫個備忘錄哦。