文:阿蜜果/2011-11-8
轉(zhuǎn)載請(qǐng)注明出處
工廠設(shè)計(jì)模式是面向?qū)ο缶幊讨凶畛S玫脑O(shè)計(jì)模式之一。它又被稱為創(chuàng)建性模式,因?yàn)樗挥脕韯?chuàng)建其他類。在應(yīng)用程序預(yù)見不到自己要?jiǎng)?chuàng)建的對(duì)象類型時(shí),就會(huì)使用工廠解決方案。在這些情況下,可以使用工廠模式作為創(chuàng)建對(duì)象的基礎(chǔ),不需要確切地了解將要?jiǎng)?chuàng)建哪些對(duì)象。
根據(jù)工廠模式實(shí)現(xiàn)的類可根據(jù)提供的數(shù)據(jù)生成一組類中某一個(gè)類的實(shí)例,通常這一組類有一個(gè)公共的抽象父類并且實(shí)現(xiàn)了相同的方法,但是這些方法針對(duì)不同的數(shù)據(jù)進(jìn)行了不同的操作。
首先需要定義一個(gè)基類,該類的子類通過不同的方法實(shí)現(xiàn)了基類中的方法。然后需要定義一個(gè)工廠類,工廠類可以根據(jù)條件生成不同的子類實(shí)例。當(dāng)?shù)玫阶宇惖膶?shí)例后,開發(fā)人員可以調(diào)用基類中的方法而不必考慮到底返回的是哪一個(gè)子類的實(shí)例。
工廠模式的示意圖如下所示:
在上面的圖形中,Client需要的Product對(duì)象不再通過new Product(…)來生成,而是通過工廠類Factory類的creates方法來獲取,工廠類一般提供多種有相關(guān)關(guān)系的對(duì)象的生成,用于解除Client類對(duì)Product類的直接耦合關(guān)系。
工廠模式常見的應(yīng)用場(chǎng)合如下:
(1)動(dòng)態(tài)實(shí)現(xiàn):例如在玩“極品飛車”這款游戲時(shí),游戲者可以根據(jù)不同品牌選擇賽車,而這個(gè)“品牌”其實(shí)就是工廠,每個(gè)工廠生產(chǎn)的賽車都不一樣,這就是典型的工廠方法的應(yīng)用場(chǎng)景。可以創(chuàng)建一些用不同方式實(shí)現(xiàn)同一接口的對(duì)象,那么可以使用一個(gè)工廠方法或簡(jiǎn)單工廠對(duì)象來簡(jiǎn)化選擇所采用的實(shí)現(xiàn)的過程。
(2)節(jié)省設(shè)置開銷:如果對(duì)象需要進(jìn)行復(fù)雜而且彼此相關(guān)的設(shè)置,那么使用工廠模式可以減少減少每種對(duì)象所需的代碼量。如果這種設(shè)置只需要為特性類型的所有實(shí)例執(zhí)行一次即可,這種作用尤其突出。把這種設(shè)置代碼放在類的構(gòu)造器函數(shù)中并不是一種高效的做法。這是因?yàn)榧幢阍O(shè)置工作已經(jīng)完成,每次創(chuàng)建新實(shí)例的時(shí)候這些代碼還是會(huì)執(zhí)行,而且這樣做會(huì)把設(shè)置代碼分散在不同的類中。
(3)用許多小型對(duì)象組成一個(gè)大對(duì)象:工廠方法用來創(chuàng)建封裝了許多較小對(duì)象的對(duì)象。例如自行車包含了許多更小的子系統(tǒng):車輪、車架、傳動(dòng)部件以及車閘等。如果不想讓某個(gè)子系統(tǒng)與較大的對(duì)象之間形成強(qiáng)耦合,而是想在運(yùn)行時(shí)從許多子系統(tǒng)中進(jìn)行挑選的話,那么工廠模式是一個(gè)很好的選擇。
在JavaScript中,單例(Singleton)模式是最基本又最有用的模式之一。這種模式提供了一種將代碼組織為一個(gè)邏輯單元的手段,這個(gè)邏輯單元中的代碼可以通過單一的變量進(jìn)行訪問。確保單例對(duì)象只有一份實(shí)例,你就可以確信自己的所有代碼使用的都是同樣的全局資源。
單例類在JavaScript中用途廣泛:
(1)可以用來劃分命名空間,以減少網(wǎng)頁中全局變量的數(shù)量;
(2)可以在一種名為分支的技術(shù)中用來封裝瀏覽器之間的差異;
(3)可以借助于單例模式,將代碼組織得更為一致,從而使代碼更容易閱讀和維護(hù)。
假設(shè)你想開一個(gè)自行車商店,每個(gè)店都有幾個(gè)型號(hào)的自行車出售。
首先創(chuàng)建一個(gè)BicycleFactory類,該類的createBicycle用于根據(jù)傳入的不同的類型時(shí)創(chuàng)建不同的自行車對(duì)象,該類的代碼如下:
在如上代碼中,createBicycle方法根據(jù)所要求自行車型號(hào)用switch創(chuàng)建一個(gè)自行車的實(shí)例,各種型號(hào)的自行車實(shí)例可以互換使用,因?yàn)槎紝?shí)現(xiàn)了Bicycle接口。
若Bicycle接口的定義如下所示(包括assemble、wash、ride和repair四個(gè)方法):
下面示意一下實(shí)現(xiàn)了Bicycle接口的Speedster:
接著創(chuàng)建一個(gè)自行車商店類,該類包含一個(gè)sellBicycle(銷售自行車)的方法,該方法首先通過工廠類的createBicycle方法獲得一輛自行車,接著對(duì)自行車進(jìn)行組裝和清洗:
若要出售一輛Speedster類型的自行車,參考代碼如下:
BicycleFactory就是簡(jiǎn)單工廠的一個(gè)很好的實(shí)例。這種模式把成員對(duì)象的創(chuàng)建工作轉(zhuǎn)交給一個(gè)外部對(duì)象。如果負(fù)責(zé)創(chuàng)建實(shí)例的方法的邏輯不會(huì)發(fā)生變化,那么一般說來使用單例或靜態(tài)方法創(chuàng)建這些成員實(shí)例都是合理的,但如果需要提供幾種不同品牌的自行車,那么更恰當(dāng)?shù)淖龇ㄊ前堰@些創(chuàng)建方法實(shí)現(xiàn)在一個(gè)類中,并從該類派生出一個(gè)子類。
待寫。
在JavaScript中使用工廠模式的主要優(yōu)點(diǎn)如下:
(1)弱化對(duì)象間的耦合;
(2)通過工廠方法而不是new關(guān)鍵字及具體類,可以把所有實(shí)例化代碼集中在一個(gè)位置,這可以大大簡(jiǎn)化更換所用的類或運(yùn)行期間動(dòng)態(tài)選擇所用的類的工作;
(3)防止代碼的重復(fù):在一個(gè)類中進(jìn)行類的實(shí)例化,可以消除重復(fù)性的代碼。
不適合使用的場(chǎng)合為:
如果根本不可能另外換用一個(gè)類,或者不需要在運(yùn)行期間在一系列可互換的類中進(jìn)行選擇,那么不應(yīng)該使用工廠方法,使用構(gòu)造函數(shù)進(jìn)行公開的實(shí)例化即可,因?yàn)檫@可以一眼看出調(diào)用的是什么構(gòu)造函數(shù),而不必去查看某個(gè)工廠方法以便知道實(shí)例化的是什么類。
(1)《JavaScript設(shè)計(jì)模式》 Ross Harmes,Dustin Dial著,謝廷晟 譯,人民郵電出版社出版
(2)《工廠模式_百度百科》:
http://baike.baidu.com/view/1306799.htm
(3)《工廠模式UML圖》:
http://apps.hi.baidu.com/share/detail/31694688