表述 (創(chuàng)建型模式)
將一個(gè)復(fù)雜對(duì)象的構(gòu)建與它的表現(xiàn)分離朴译,使得同樣的構(gòu)建過(guò)程可以創(chuàng)建不同的表現(xiàn)
一個(gè)復(fù)雜對(duì)象的創(chuàng)建勺良,通常由幾個(gè)部分采用一定的步驟構(gòu)成往史,由于需求變化刊头,這個(gè)復(fù)雜對(duì)象的各個(gè)部分面臨不斷的改變黍瞧,但是各個(gè)部分組合在一起的這個(gè)步驟是相對(duì)穩(wěn)定的,這就是建造者模式
建造者類圖
Builder:為創(chuàng)建一個(gè)產(chǎn)品對(duì)象的各個(gè)部分指定的抽象類
ConcreteBuilder:實(shí)現(xiàn)Builder抽象類中的接口原杂,以構(gòu)造和組裝該產(chǎn)品的各個(gè)部分印颤,定義并明確它所創(chuàng)建的表示,并提供一個(gè)檢索的接口
Director:根據(jù)需求構(gòu)建產(chǎn)品穿肄,用它來(lái)隔離用戶與建造過(guò)程的關(guān)聯(lián)
Product:被構(gòu)造的復(fù)雜對(duì)象
優(yōu)點(diǎn)
使得建造者代碼表現(xiàn)代碼分離年局,由于建造者隱藏了該產(chǎn)品是如何組裝的际看,所以若需要改變一個(gè)產(chǎn)品的內(nèi)部表示,只需要再定義一個(gè)具體的建造者就可以了
使得構(gòu)建過(guò)程和表現(xiàn)分離矢否,因此若需要改變一個(gè)產(chǎn)品的表現(xiàn)仲闽,只需要重新定義一個(gè)具體的建造者就可以了(這句話理解起來(lái)有點(diǎn)難度,還是拿車(chē)來(lái)打比方僵朗,我們將車(chē)的組裝過(guò)程獨(dú)立出來(lái)赖欣,用這個(gè)組裝過(guò)程,我們即可以組裝寶馬車(chē)验庙,也可以組裝奔馳車(chē)顶吮,或者其他的車(chē)型,我們只需要重新定義一個(gè)具體的建造者(用于產(chǎn)品表現(xiàn)的類)就可以了)
使用場(chǎng)景
- 需要?jiǎng)?chuàng)建涉及各種部件的復(fù)雜對(duì)象粪薛,創(chuàng)建對(duì)象的步驟應(yīng)該獨(dú)立于部件的組裝方式
- 構(gòu)建過(guò)程需要以不同的方式組裝對(duì)象
建造者模式與工廠模式對(duì)比
建造者 | 工廠 |
---|---|
構(gòu)建復(fù)雜對(duì)象 | 構(gòu)建簡(jiǎn)單或復(fù)雜對(duì)象 |
以多個(gè)步驟構(gòu)建對(duì)象 | 以單一步驟構(gòu)建對(duì)象 |
以多種方式構(gòu)建對(duì)象 | 一單一方式構(gòu)建對(duì)象 |
在構(gòu)建過(guò)程的最后一步返產(chǎn)品 | 立刻返回產(chǎn)品 |
專注一個(gè)特定產(chǎn)品 | 強(qiáng)調(diào)一套產(chǎn)品 |
示例
需求v1:在中關(guān)村想買(mǎi)個(gè)電腦悴了,目前就想買(mǎi)個(gè)蘋(píng)果本
蘋(píng)果本就是Product,它的logo违寿、name湃交、price就是組成它的各個(gè)部分,也就是ConcreteBuilder藤巢,售貨員就是Director
//為創(chuàng)建產(chǎn)品對(duì)象各個(gè)部件指定的抽象接口
class ComputerBuilder {
func logo() {
}
func name() {
}
func price() {
}
}
//具體產(chǎn)品巡揍,也就是的建造者,實(shí)現(xiàn)Builder接口菌瘪,構(gòu)建各個(gè)部件
class AppleBuilder : ComputerBuilder {
override func logo() {
print("?")
}
override func name() {
print("Apple")
}
override func price() {
print("1w")
}
}
//根據(jù)需求構(gòu)建的產(chǎn)品
class ComputerShopDirector {
var computer:ComputerBuilder
init(computer:ComputerBuilder) {
self.computer = computer
}
func show() {
self.computer.logo()
self.computer.name()
self.computer.price()
}
}
客戶端調(diào)用:
//創(chuàng)建者
let appleBuild = AppleBuilder()
// 組裝
let appleDirector = ComputerShopDirector.init(computer: appleBuild)
appleDirector.show()
//log:
//?
//Apple
//1w
需求v2:在電腦城對(duì)比后,不買(mǎi)蘋(píng)果本阱当,決定買(mǎi)聯(lián)想了
只需要去繼承ComputerBuilder俏扩,實(shí)現(xiàn)抽象類方法,客戶端直接調(diào)用即可
class LenovoBuilder : ComputerBuilder {
override func logo() {
print("Lenovo")
}
override func name() {
print("聯(lián)想")
}
override func price() {
print("5k")
}
}
客戶端:
let lenovoBuild = LenovoBuilder()
let lenovoDirector = ComputerShopDirector.init(computer: lenovoBuild)
lenovoDirector.show()
//log:
//Lenovo
//聯(lián)想
//5k