游戲代碼淺讀室/#1 建造者模式(Builder)
一、概述
本系列專欄為筆者學(xué)習(xí)體會隨筆 沒有絕對專業(yè)性,主要內(nèi)容為對游戲設(shè)計模式及其他內(nèi)容的理解和應(yīng)用實例。
注:設(shè)計模式只是一種簡單的設(shè)計思路,我們應(yīng)該活用思路而不是按圖索驥,適當(dāng)修改能更好地應(yīng)用于自己的游戲中。
在GoF(Gang of Four,四人組)的定義下,設(shè)計模式一共有23種常見的模式,這些設(shè)計模式分為三大類:創(chuàng)建型模式(Creational Pattern)、結(jié)構(gòu)型模式(Structural Pattern)和行為型模式(Behavioral Pattern)。我們今天的主角就是創(chuàng)建型模式中的建造者模式(Builder Pattern)。
一般是這樣定義建造者模式的:“將一個復(fù)雜對象的構(gòu)建與其表示分離,使得同樣的構(gòu)建過程可以創(chuàng)建不同的表示。”也就是說身為創(chuàng)建型的建造者模式是可以幫助我們?nèi)?gòu)建一個復(fù)雜的對象,并且將構(gòu)建層與表示層的代碼相分離 從而解耦代碼,并使得這種構(gòu)建方法可以廣泛利用。這種描述難免不會讓我們聯(lián)想到另一種熟悉的創(chuàng)建型模式——工廠模式(在筆者的另一專欄中已介紹過),這兩者的區(qū)別又是什么呢?
二、分析
學(xué)習(xí)過C#、Java等代碼的讀者們都應(yīng)該知道,我們構(gòu)建一個類或者成為對象的時候,會為了將其描述地具體生動賦予很多的變量 屬性,并使用構(gòu)造函數(shù)規(guī)范該對象被具體構(gòu)建出來時候的構(gòu)建流程。
例如,我們在RPG游戲中想要構(gòu)建一個人物角色,基本上都會先建構(gòu)一個基本的角色模板,并為他賦予外貌特征、性別、年齡等等屬性,當(dāng)我們想要創(chuàng)建一個具體人物的時候 就可以利用這個模板填入人物數(shù)據(jù),從而創(chuàng)造一個真實的人物角色。
這個流程確實簡單方便,但如果當(dāng)我們想要構(gòu)建的角色太過于復(fù)雜,需要很多的屬性來讓他在這個世界中更加真實 獨特,這套流程往往會讓我們的工作更加繁瑣 枯燥 浪費時間。這時,建造者模式就可以來救場了!
也就是說:當(dāng)我們需要構(gòu)造一個構(gòu)造參數(shù)數(shù)量超過4個的類,且部分參數(shù)是可選的時,考慮使用建造者模式。建造者模式是為構(gòu)建復(fù)雜對象服務(wù)的。
常見的構(gòu)造方法:
可以很明顯看出,上述的創(chuàng)建方法在創(chuàng)建復(fù)雜角色中都缺乏可讀性,并且屬性一多起來就相當(dāng)?shù)幕靵y,這時我們可以使用?建造者模式(Builder)。
三、建造者模式
一般情況下,建造者模式中有四種角色:
1. 產(chǎn)品(Product):我們需要去構(gòu)建的具體對象。
2. 抽象建造者(Builder):建造者的抽象基類(有時也會作為接口使用),定義了一個建造者的抽象方法,一般為構(gòu)建步驟方法和產(chǎn)品獲取方法。
3. 具體建造者(ConcreteBuilder):繼承了Builder類或?qū)崿F(xiàn)了IBuilder接口,實現(xiàn)了對象各個部件的構(gòu)建方法和產(chǎn)品組裝獲取方法。
4. 指揮者(也叫導(dǎo)演,Director):可以視為管理類,是建造者系統(tǒng)與外部代碼的連接橋梁,外部通過調(diào)用指揮者類中的Construct()方法來讓建造者為我們構(gòu)建對象。

四、動動手
讓我們來使用建造者模式來創(chuàng)建一位RPG游戲中的角色。

首先,我們要先完成一個Product,這里安排是寫一個Character作為基類,并依靠這個基類來創(chuàng)建不同職業(yè)的角色。
有了Product后,我們可以開始動手編寫對應(yīng)的抽象Builder了,在這段中我們的目的是定義這類Builder的基本功能。
接著我們來創(chuàng)建一個勇者職業(yè)的Builder類,之后我們想要創(chuàng)建一個勇者角色的時候就會使用這個Builder。
最終會由指揮者將所有的Builder統(tǒng)一管理,并與外部相交互,當(dāng)調(diào)用傳入的是HeroBuilder,那么Director就會自動為我們創(chuàng)建了一個勇者角色,而外部所要做的就是定義好角色的必要屬性,勇者職業(yè)的特性都會由HeroBuilder幫助我們自動定義。
五、設(shè)計反思
建造者模式的優(yōu)缺點:
優(yōu)點:
建造者模式能夠為我們提前封裝好對應(yīng)類型的相關(guān)細節(jié),例如我們想要創(chuàng)建一個魔法師角色,那么就可以使用建造者模式提前為我們封裝好魔法師角色的細節(jié)特性,外部就只需考慮該角色的基礎(chǔ)面板。
每個Builder之間相互獨立,我們可以自由地更換Builder來創(chuàng)建不同類型的角色,拓展性好。并且系統(tǒng)內(nèi)部角色的創(chuàng)建過程是邏輯清晰的。
缺點:
建造者模式創(chuàng)建的對象一般具有較多的共同特點,也就是必要屬性較多,如果不同類型的對象之間差異性過大,不建議使用建造者模式。
對象類型細分越多,我們就需要創(chuàng)建越多的Buidler,當(dāng)我們的Builder類越來越多的時候,就會很難進行維護。
非必要屬性的內(nèi)容在Builder內(nèi)部進行設(shè)定,沒有參數(shù)引入,這是一個建造者模式的特點,但有些情況下這反而會讓建造者模式不適合使用。
因此,一般情況下筆者的建議是盡量減少同類Builder之間的差異性。
