這個設計模式主要是解決複雜物件的建立問題, 使這個抽象過程的不同實現方法可以構造出不同表現(屬性)的物件。
建造者模式是一步一步建立乙個複雜的物件,它允許使用者只通過指定複雜物件的型別和內容就可以構建它們,使用者不需要知道內部的具體構建細節。例如,一輛汽車由輪子,發動機以及其他零件組成,對於普通人而言,我們使用的只是一輛完整的車,這時,我們需要加入乙個構造者,讓他幫我們把這些元件按序組裝成為一輛完整的車。
有個訂單:賓士、寶馬的車輛模型都交給我我們公司製作了,不過這次又額外增加了乙個需求: 汽車的啟動、停止、喇叭聲音、引擎聲音都由客戶自己控制,他想什麼順序就什麼順序。
首先,賓士、寶馬都是乙個產品,他們有共有的屬性,但是可能賓士是先有引擎聲音 然後再啟動。寶馬呢是先啟動後有引擎聲音
<?php
/** * created by 憧憬.
*/abstract class carmodel}}
// 允許客戶端自己設定啟動順序 想先幹嘛 就往陣列裡面指定
final public function setsequence($sequence)
}/**
* 賓士車的實現
* class benzmodel
*/class benzmodel extends carmodel
protected function stop()
protected function alarm()
protected function engineboom()
}/**
* 寶馬車的實現
* class bmwmodel
*/class bmwmodel extends carmodel
protected function stop()
protected function alarm()
protected function engineboom()
}// 我先要個賓士的模型,這個模型的要求是跑的時候, 先發動引擎,然後再掛檔啟動,然後停下來,不需要喇叭,那怎麼實現呢?
$benzmodel = new benzmodel();
$benzmodel->setsequence(['engineboom', 'start', 'stop']);
$benzmodel->run();
echo php_eol;
/** * 上面雖然實現了基本隨意更換構建汽車的過程,然後還有其他車實現,例如:
* 寶馬的車只要啟動和停止,其餘什麼都不要, 還有其他車,先喇叭,然後啟動,然後停止,.....
* 這樣就導致一直去訪問產品類 **產生了耦合
*//**
* 約束需要什麼順序的車
* class carbuilder
*/abstract class carbuilder
/** * 賓士的構建者
* class benzbuilder
*/class benzbuilder extends carbuilder
public function getcarmodel()
// 設定啟動構造順序
public function setsequence($sequence)
}/**
* 寶馬構建者
* class bmwbuilder
*/class bmwbuilder extends carbuilder
public function getcarmodel()
// 設定啟動構造順序
public function setsequence($sequence)
}// 構建乙個賓士的
$benzbuilder = new benzbuilder();
$benzbuilder->setsequence(['engineboom', 'start', 'stop']);
$benzbuilder->getcarmodel()->run();
// 那如果需要再構造乙個寶馬的也是一樣的 這樣就不需要直接訪問產品類了
echo php_eol;
$bmwbuilder = new bmwbuilder();
$bmwbuilder->setsequence(['engineboom', 'start', 'stop']);
$bmwbuilder->getcarmodel()->run();
/** * 那這有個這樣的需求,這四個過程 (start,stop,alarm,engineboom)按照排列組合有很多種,
* 那我們怎麼滿足這種需求呢?也就是要有個類 來安排這幾個方法組合,
* 就像導演安排演員一樣,那個先出場那個後出場,那個不出場,我們這個也叫導演類,
*///型號的賓士車輛模型是只有啟動(start)、停止(stop)方法,其他的引擎聲音、喇叭都沒有;
//b 型號的賓士車是先發動引擎(engine boom),然後啟動(star),再然後停車(stop),沒有喇叭;
//c 型號的寶馬車是先喇叭叫一下(alarm),然後(start),再然後是停車(stop),引擎不轟鳴;
//d 型號的寶馬車就乙個啟動(start),然後一路跑到黑,永動機,沒有停止方法,沒有喇叭,沒有引擎轟鳴; e 型號、f 型號...等等,可以有很多,啟動(start)、停止(stop)、喇叭(alarm)、引擎轟鳴(engine boom)
class director
// a型別賓士 先start,然後stop,其他什麼引擎了,喇叭一概沒有
public function getabenzmodel()
// b型別賓士 是先發動引擎,然後啟動,然後停止,沒有喇叭
public function getbbenzmodel()
// c型號的寶馬車是先按下喇叭(炫耀嘛),然後啟動,然後停止
public function getcbmwmodel()
// d型別的寶馬車只有乙個功能,就是跑,啟動起來就跑,永遠不停止,牛叉
public function getdbmwmodel()
}// 然後 client 程式就只與 director 打交道了
class client
//100w輛b型別的賓士車
for ($i = 0; $i < 1000000;
$i++)
//1000w量c型別的寶馬車
for ($i = 0; $i < 10000000; $i++)
}}client::main();
注意,這個建造者模式和工廠模式非常相似 但是記住一點你就可以游刃有餘的使用了: 建造者模式最主要功能是基本方法的呼叫順序安排,也就是這些基本方 法已經實現了;而工廠方法則重點是建立,你要什麼物件我創造乙個物件出來,組裝順序則不是他關心的
建造者模式使用的場景,產品類非常的複雜,或者產品類中的呼叫順序不同產生了不同的效能,這個時候使用建造者模式是非常合適。
我曾在乙個銀行交易類專案中遇到了這個問題,乙個產品的定價計算模型有 n 多 種,每個模型有固定的計算步驟,計算非常複雜,專案中就使用了建造者模式;
這篇文章參考自24種設計模式介紹與六大設計原則
設計模式 建造者模式
在gof的23種設計模式中對builder pattern的定義是 將乙個複雜物件的構建與它的表示分離,使得同樣的構建過程可以建立不同的表示。從程式角度來說,就是在基類定義某種事物建立的過程或業務流程,在子類進行重寫或是使用基類方法。這樣建立出來的例項不會因為過程或流程的丟失而使業務失敗。舉例來說,...
設計模式建造者模式
今天看了乙個設計模式。總結下,以免忘了。如何引入建造者模式的呢?作者舉了個例子。建造小人。當然需要 頭,左手,右手,左腳,右腳,軀幹。建造的過程使用 使用類裡面的方法就行了。但是如果需要乙個胖的小人,乙個瘦的小人呢?就需要重新構造乙個胖人類,乙個瘦人類。當然 使用者還需要自己處理構造的過程。這樣 就...
設計模式 建造者模式
定義 將乙個複雜的物件的構建與它的表示分離,是的同樣的構建過程可以建立不同的表示。包括的要素 1 產品類 2 抽象建造者或者介面 3 建造者 4 導演類 建造者模式的優點 首先,建造者模式的封裝很好,使用建造者模式可以有效地封裝變化,注意在使用建造者模式的場景中,一般產品類和建造者介面是比較穩定的,...