一、什么是建造者模式
建造者模式是設(shè)計模式的一種,將一個復(fù)雜對象的構(gòu)建與它的表示分離治筒,使得同樣的構(gòu)建過程可以創(chuàng)建不同的表示落塑。
建造者模式是將一個復(fù)雜對象的構(gòu)建過程與它的實現(xiàn)表示分離,使得同樣的構(gòu)建過程可以創(chuàng)建不同的表示攻询,屬于創(chuàng)建型模式。使用創(chuàng)建者模式對于用戶而言只需要制定需要建造的類就可以獲得對象,建造過程及細(xì)節(jié)不需要了解胆筒。
建造者模式適用于創(chuàng)建對象需要很多步驟,但是步驟的順序不一定固定诈豌。如果一個對象有非常復(fù)雜的內(nèi)部結(jié)構(gòu)仆救,可以將復(fù)雜對象的創(chuàng)建和使用進(jìn)行分離。
二矫渔、建造者模式的結(jié)構(gòu)
角色 | 含義 |
---|---|
產(chǎn)品角色 | 它是包含多個組成部件的復(fù)雜對象彤蔽,由具體建造者來創(chuàng)建其各個零部件 |
抽象建造者 | 它是一個包含創(chuàng)建產(chǎn)品各個子部件的抽象方法的接口,通常還包含一個返回復(fù)雜產(chǎn)品的方法 |
具體建造者 | 實現(xiàn) Builder 接口庙洼,完成復(fù)雜產(chǎn)品的各個部件的具體創(chuàng)建方法顿痪。可以有不同的具體建造者 |
指揮者 | 它調(diào)用建造者對象中的部件構(gòu)造與裝配方法完成復(fù)雜對象的創(chuàng)建油够,在指揮者中不涉及具體產(chǎn)品的信息 |
三蚁袭、建造者模式的代碼實現(xiàn)
python實現(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實現(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)缺點
優(yōu)點
客戶端不必知道產(chǎn)品內(nèi)部組成的細(xì)節(jié)石咬,將產(chǎn)品本身與產(chǎn)品的創(chuàng)建過程解耦揩悄,使得相同的創(chuàng)建過程可以創(chuàng)建不同的產(chǎn)品對象。
每一個具體建造者都獨立鬼悠,因此可以方便地替換具體建造者或增加新的具體建造者删性, 用戶使用不同的具體建造者即可得到不同的產(chǎn)品對象 亏娜。
- 可以更加精細(xì)地控制產(chǎn)品的創(chuàng)建過程 。將復(fù)雜產(chǎn)品的創(chuàng)建步驟分解在不同的方法中镇匀,使得創(chuàng)建過程更加清晰照藻,也更方便使用程序來控制創(chuàng)建過程。
- 增加新的具體建造者無須修改原有類庫的代碼汗侵,指揮者類針對抽象建造者類編程幸缕,系統(tǒng)擴(kuò)展方便,符合“開閉”晰韵。
缺點
- 當(dāng)建造者過多時发乔,會產(chǎn)生很多類,難以維護(hù)雪猪。
- 建造者模式所創(chuàng)建的產(chǎn)品一般具有較多的共同點栏尚,其組成部分相似,若產(chǎn)品之間的差異性很大只恨,則不適合使用該模式译仗,因此其使用范圍受到一定限制。
- 若產(chǎn)品的內(nèi)部變化復(fù)雜官觅,可能會導(dǎo)致需要定義很多具體建造者類來實現(xiàn)這種變化纵菌,導(dǎo)致系統(tǒng)變得很龐大。
五休涤、建造者模式的應(yīng)用場景
建造者模式主要適用于以下應(yīng)用場景:
- 相同的方法咱圆,不同的執(zhí)行順序,產(chǎn)生不同的結(jié)果功氨。
- 多個部件或零件序苏,都可以裝配到一個對象中,但是產(chǎn)生的結(jié)果又不相同捷凄。
- 產(chǎn)品類非常復(fù)雜忱详,或者產(chǎn)品類中不同的調(diào)用順序產(chǎn)生不同的作用。
- 初始化一個對象特別復(fù)雜纵势,參數(shù)多踱阿,而且很多參數(shù)都具有默認(rèn)值。
六钦铁、對比
工廠模式和建造者模式的對比
建造者模式唯一區(qū)別于工廠模式的是是否是復(fù)雜對象的創(chuàng)建。也就是說才漆,如果創(chuàng)建簡單對象牛曹,通常都是使用工廠模式進(jìn)行創(chuàng)建,而如果創(chuàng)建復(fù)雜對象醇滥,就可以考慮使用建造者模式黎比。
當(dāng)需要創(chuàng)建的產(chǎn)品具備復(fù)雜創(chuàng)建過程時超营,可以抽取出共性創(chuàng)建過程,然后交由具體實現(xiàn)類自定義創(chuàng)建流程阅虫,使得同樣的創(chuàng)建行為可以生產(chǎn)出不同的產(chǎn)品演闭,分離了創(chuàng)建與表示,使創(chuàng)建產(chǎn)品的靈活性大大增加颓帝。
- 建造者模式更加注重方法的調(diào)用順序米碰,工廠模式注重創(chuàng)建對象。
- 創(chuàng)建對象的力度不同购城,建造者模式創(chuàng)建復(fù)雜的對象吕座,由各種復(fù)雜的部件組成,工廠模式創(chuàng)建出來的對象都一樣
- 關(guān)注重點不一樣瘪板,工廠模式只需要把對象創(chuàng)建出來就可以了吴趴,而建造者模式不僅要創(chuàng)建出對象,還要知道對象由哪些部件組成侮攀。
- 建造者模式根據(jù)建造過程中的順序不一樣锣枝,最終對象部件組成也不一樣。
七兰英、總結(jié)
建造者模式的使用場合是當(dāng)創(chuàng)建復(fù)雜對象時撇叁,把創(chuàng)建對象成員和裝配方法分離出來,放在建造者類中去實現(xiàn)箭昵,用戶使用該復(fù)雜對象時税朴,不用理會它的創(chuàng)建和裝配過程,只關(guān)心它的表示形式家制。