一、什么是建造者模式
建造者模式是設(shè)計(jì)模式的一種,將一個(gè)復(fù)雜對(duì)象的構(gòu)建與它的表示分離,使得同樣的構(gòu)建過(guò)程可以創(chuàng)建不同的表示。
建造者模式是將一個(gè)復(fù)雜對(duì)象的構(gòu)建過(guò)程與它的實(shí)現(xiàn)表示分離,使得同樣的構(gòu)建過(guò)程可以創(chuàng)建不同的表示,屬于創(chuàng)建型模式。使用創(chuàng)建者模式對(duì)于用戶而言只需要制定需要建造的類就可以獲得對(duì)象,建造過(guò)程及細(xì)節(jié)不需要了解。
建造者模式適用于創(chuàng)建對(duì)象需要很多步驟,但是步驟的順序不一定固定。如果一個(gè)對(duì)象有非常復(fù)雜的內(nèi)部結(jié)構(gòu),可以將復(fù)雜對(duì)象的創(chuàng)建和使用進(jìn)行分離。
二、建造者模式的結(jié)構(gòu)
| 角色 | 含義 |
|---|---|
| 產(chǎn)品角色 | 它是包含多個(gè)組成部件的復(fù)雜對(duì)象,由具體建造者來(lái)創(chuàng)建其各個(gè)零部件 |
| 抽象建造者 | 它是一個(gè)包含創(chuàng)建產(chǎn)品各個(gè)子部件的抽象方法的接口,通常還包含一個(gè)返回復(fù)雜產(chǎn)品的方法 |
| 具體建造者 | 實(shí)現(xiàn) Builder 接口,完成復(fù)雜產(chǎn)品的各個(gè)部件的具體創(chuàng)建方法。可以有不同的具體建造者 |
| 指揮者 | 它調(diào)用建造者對(duì)象中的部件構(gòu)造與裝配方法完成復(fù)雜對(duì)象的創(chuàng)建,在指揮者中不涉及具體產(chǎn)品的信息 |
三、建造者模式的代碼實(shí)現(xiàn)
python實(shí)現(xiàn)
from abc import ABCMeta, abstractmethod
class Player(object):
def __init__(self, face=None, leg=None):
self.face = face
self.leg = leg
def __str__(self):
return f'{self.face}--{self.leg}'
# 抽象建造者
class BaseBuilder(metaclass=ABCMeta):
@abstractmethod
def build_face(self):
pass
@abstractmethod
def build_leg(self):
pass
class BeautifulBuilder(BaseBuilder):
def __init__(self):
self.player = Player()
def build_face(self):
self.player.face = '美女的臉'
def build_leg(self):
self.player.leg = '美女的腿'
class MonsterBuilder(BaseBuilder):
def __init__(self):
self.player = Player()
def build_leg(self):
self.player.leg = '怪獸的腿'
def build_face(self):
self.player.face = '怪獸的臉'
class PlayerDirector(object):
def build_player(self, builder):
builder.build_face()
builder.build_leg()
return builder.player
if __name__ == '__main__':
builder = MonsterBuilder()
director = PlayerDirector()
p = director.build_player(builder)
print(p)
golang實(shí)現(xiàn)
type Person struct {
name, sex, address string
age int
}
func (p *Person) PrintInfo() {
fmt.Printf("姓名: %s, 年齡: %d, 性別: %s, 住址: %s\n", p.name, p.age, p.sex, p.address)
}
type PersonBuilder struct {
person *Person
}
func NewPersonBuilder() *PersonBuilder {
return &PersonBuilder{person: &Person{}}
}
func (p *PersonBuilder) Name(name string) *PersonBuilder {
p.person.name = name
return p
}
func (p *PersonBuilder) Sex(sex string) *PersonBuilder {
p.person.sex = sex
return p
}
func (p *PersonBuilder) Address(address string) *PersonBuilder {
p.person.address = address
return p
}
func (p *PersonBuilder) Age(age int) *PersonBuilder {
p.person.age = age
return p
}
func (p *PersonBuilder) Build() *Person {
return p.person
}
func main() {
p := NewPersonBuilder().
Name("張三").
Age(18).
Sex("男").
Address("上海").
Build()
p.PrintInfo()
}
四、建造者模式的優(yōu)缺點(diǎn)
優(yōu)點(diǎn)
客戶端不必知道產(chǎn)品內(nèi)部組成的細(xì)節(jié),將產(chǎn)品本身與產(chǎn)品的創(chuàng)建過(guò)程解耦,使得相同的創(chuàng)建過(guò)程可以創(chuàng)建不同的產(chǎn)品對(duì)象。每一個(gè)具體建造者都獨(dú)立,因此可以方便地替換具體建造者或增加新的具體建造者, 用戶使用不同的具體建造者即可得到不同的產(chǎn)品對(duì)象 。- 可以更加精細(xì)地控制產(chǎn)品的創(chuàng)建過(guò)程 。將復(fù)雜產(chǎn)品的創(chuàng)建步驟分解在不同的方法中,使得創(chuàng)建過(guò)程更加清晰,也更方便使用程序來(lái)控制創(chuàng)建過(guò)程。
- 增加新的具體建造者無(wú)須修改原有類庫(kù)的代碼,指揮者類針對(duì)抽象建造者類編程,系統(tǒng)擴(kuò)展方便,符合“開(kāi)閉”。
缺點(diǎn)
- 當(dāng)建造者過(guò)多時(shí),會(huì)產(chǎn)生很多類,難以維護(hù)。
- 建造者模式所創(chuàng)建的產(chǎn)品一般具有較多的共同點(diǎn),其組成部分相似,若產(chǎn)品之間的差異性很大,則不適合使用該模式,因此其使用范圍受到一定限制。
- 若產(chǎn)品的內(nèi)部變化復(fù)雜,可能會(huì)導(dǎo)致需要定義很多具體建造者類來(lái)實(shí)現(xiàn)這種變化,導(dǎo)致系統(tǒng)變得很龐大。
五、建造者模式的應(yīng)用場(chǎng)景
建造者模式主要適用于以下應(yīng)用場(chǎng)景:
- 相同的方法,不同的執(zhí)行順序,產(chǎn)生不同的結(jié)果。
- 多個(gè)部件或零件,都可以裝配到一個(gè)對(duì)象中,但是產(chǎn)生的結(jié)果又不相同。
- 產(chǎn)品類非常復(fù)雜,或者產(chǎn)品類中不同的調(diào)用順序產(chǎn)生不同的作用。
- 初始化一個(gè)對(duì)象特別復(fù)雜,參數(shù)多,而且很多參數(shù)都具有默認(rèn)值。
六、對(duì)比
工廠模式和建造者模式的對(duì)比
建造者模式唯一區(qū)別于工廠模式的是是否是復(fù)雜對(duì)象的創(chuàng)建。也就是說(shuō),如果創(chuàng)建簡(jiǎn)單對(duì)象,通常都是使用工廠模式進(jìn)行創(chuàng)建,而如果創(chuàng)建復(fù)雜對(duì)象,就可以考慮使用建造者模式。
當(dāng)需要?jiǎng)?chuàng)建的產(chǎn)品具備復(fù)雜創(chuàng)建過(guò)程時(shí),可以抽取出共性創(chuàng)建過(guò)程,然后交由具體實(shí)現(xiàn)類自定義創(chuàng)建流程,使得同樣的創(chuàng)建行為可以生產(chǎn)出不同的產(chǎn)品,分離了創(chuàng)建與表示,使創(chuàng)建產(chǎn)品的靈活性大大增加。
- 建造者模式更加注重方法的調(diào)用順序,工廠模式注重創(chuàng)建對(duì)象。
- 創(chuàng)建對(duì)象的力度不同,建造者模式創(chuàng)建復(fù)雜的對(duì)象,由各種復(fù)雜的部件組成,工廠模式創(chuàng)建出來(lái)的對(duì)象都一樣
- 關(guān)注重點(diǎn)不一樣,工廠模式只需要把對(duì)象創(chuàng)建出來(lái)就可以了,而建造者模式不僅要?jiǎng)?chuàng)建出對(duì)象,還要知道對(duì)象由哪些部件組成。
- 建造者模式根據(jù)建造過(guò)程中的順序不一樣,最終對(duì)象部件組成也不一樣。
七、總結(jié)
建造者模式的使用場(chǎng)合是當(dāng)創(chuàng)建復(fù)雜對(duì)象時(shí),把創(chuàng)建對(duì)象成員和裝配方法分離出來(lái),放在建造者類中去實(shí)現(xiàn),用戶使用該復(fù)雜對(duì)象時(shí),不用理會(huì)它的創(chuàng)建和裝配過(guò)程,只關(guān)心它的表示形式。