008設(shè)計(jì)模式--建造者模式(Bulider Pattern)

一、什么是建造者模式

建造者模式是設(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)心它的表示形式。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容