摘要:基于工廠角色和產(chǎn)品角色的多態(tài)性設(shè)計(jì)是工廠方法模式的關(guān)鍵。工廠方法模式之所以又被稱(chēng)為多態(tài)工廠模式,是因?yàn)樗械木唧w工廠類(lèi)都具有同一抽象父類(lèi)。工廠方法模式總結(jié)工廠方法模式是簡(jiǎn)單工廠模式的進(jìn)一步抽象和推廣。
JavaScript工廠模式
首先需要說(shuō)一下工廠模式。工廠模式根據(jù)抽象程度的不同分為三種
簡(jiǎn)單工廠模式
工廠方法模式
抽象工廠模式
1.簡(jiǎn)單工廠模式簡(jiǎn)單工廠模式:又稱(chēng)為靜態(tài)工廠方法模式,它屬于類(lèi)創(chuàng)建型模式。
在簡(jiǎn)單工廠模式中,可以根據(jù)參數(shù)的不同返回不同類(lèi)的實(shí)例。
由工廠對(duì)象決定創(chuàng)建某一種產(chǎn)品對(duì)象類(lèi)的實(shí)例。
// #簡(jiǎn)單工廠模式第一種 /** * 足球類(lèi) */ var FootBall = function () { this.play = function () { console.log("我在踢足球"); } } /** * 籃球類(lèi) */ var BasketBall = function () { this.play = function () { console.log("我在打籃球"); } } var football = new FootBall(); football.play(); var basketball = new BasketBall(); basketball.play(); /** * 球類(lèi)工廠 */ var Ball = function(name) { switch (name) { case "足球": return new FootBall(); break; case "籃球": return new BasketBall(); break; } } var football = Ball("足球"); football.play(); var basketball = Ball("籃球"); basketball.play(); // #簡(jiǎn)單工廠模式第一種end
這段案例可以簡(jiǎn)單的這么去理解,假設(shè)我們需要多個(gè)球,我們希望在使用球的時(shí)候,只需要告訴管理員我們需要的球的類(lèi)型,不需要一個(gè)個(gè)去找對(duì)應(yīng)的球這個(gè)管理員就相對(duì)于工廠函數(shù)。
簡(jiǎn)單講就是使用簡(jiǎn)單工廠模式,那么你就不需要關(guān)心它的具體實(shí)現(xiàn),你只需要知道你要使用的類(lèi)型,那么工廠函數(shù)會(huì)自動(dòng)幫你去做對(duì)應(yīng)的事情
// #簡(jiǎn)單工廠模式第二種 /** * 球類(lèi)工廠 */ var Ball = function(name) { // 創(chuàng)建一個(gè)對(duì)象,對(duì)對(duì)象擴(kuò)展擴(kuò)展屬性還有方法 var o = new Object(); o.name = name; //默認(rèn)的方法 如果在加上一個(gè)羽毛球類(lèi),這時(shí)候就不需要補(bǔ)充play方法 o.play = function () { console.log("我在打"+name); } if (name === "足球") { o.play = function () { console.log("我在踢"+name); } }else if (name === "籃球") { o.play = function () { console.log("我在打"+name); } } // 將對(duì)象返回 return o; } var football = Ball("足球"); football.play(); var basketball = Ball("籃球"); basketball.play(); // #簡(jiǎn)單工廠模式第二種end
這段案例是用對(duì)象的方式代替多個(gè)類(lèi),把相同點(diǎn)抽離出來(lái),
不同點(diǎn)在一一做類(lèi)型判斷,這樣也是簡(jiǎn)單工廠模式實(shí)現(xiàn)的另一種方式
簡(jiǎn)單工廠模式的優(yōu)點(diǎn):
工廠類(lèi)含有必要的判斷邏輯,可以決定在什么時(shí)候創(chuàng)建哪一個(gè)產(chǎn)品類(lèi)的實(shí)例,客戶(hù)端可以免除直接創(chuàng)建產(chǎn)品對(duì)象的責(zé)任,而僅僅“消費(fèi)”產(chǎn)品;簡(jiǎn)單工廠模式通過(guò)這種做法實(shí)現(xiàn)了對(duì)責(zé)任的分割,它提供了專(zhuān)門(mén)的工廠類(lèi)用于創(chuàng)建對(duì)象
客戶(hù)端無(wú)須知道所創(chuàng)建的具體產(chǎn)品類(lèi)的類(lèi)名,只需要知道具體產(chǎn)品類(lèi)所對(duì)應(yīng)的參數(shù)即可,對(duì)于一些復(fù)雜的類(lèi)名,通過(guò)簡(jiǎn)單工廠模式可以減少使用者的記憶量。
簡(jiǎn)單工廠模式的缺點(diǎn)
由于工廠類(lèi)集中了所有產(chǎn)品創(chuàng)建邏輯,一旦不能正常工作,整個(gè)系統(tǒng)都要受到影響。
使用簡(jiǎn)單工廠模式將會(huì)增加系統(tǒng)中類(lèi)的個(gè)數(shù),在一定程序上增加了系統(tǒng)的復(fù)雜度和理解難度。
系統(tǒng)擴(kuò)展困難,一旦添加新產(chǎn)品就不得不修改工廠邏輯,在產(chǎn)品類(lèi)型較多時(shí),有可能造成工廠邏輯過(guò)于復(fù)雜,不利于系統(tǒng)的擴(kuò)展和維護(hù)。
簡(jiǎn)單工廠模式的適用情況
在以下情況下可以使用簡(jiǎn)單工廠模式:
工廠類(lèi)負(fù)責(zé)創(chuàng)建的對(duì)象比較少:由于創(chuàng)建的對(duì)象較少,不會(huì)造成工廠方法中的業(yè)務(wù)邏輯太過(guò)復(fù)雜。
客戶(hù)端只知道傳入工廠類(lèi)的參數(shù),對(duì)于如何創(chuàng)建對(duì)象不關(guān)心:客戶(hù)端既不需要關(guān)心創(chuàng)建細(xì)節(jié),甚至連類(lèi)名都不需要記住,只需要知道類(lèi)型所對(duì)應(yīng)的參數(shù)。
簡(jiǎn)單工廠模式總結(jié)
簡(jiǎn)單工廠模式的要點(diǎn)在于:當(dāng)你需要什么,只需要傳入一個(gè)正確的參數(shù),就可以獲取你所需要的對(duì)象,而無(wú)須知道其創(chuàng)建細(xì)節(jié)。
簡(jiǎn)單工廠模式最大的優(yōu)點(diǎn)在于實(shí)現(xiàn)對(duì)象的創(chuàng)建和對(duì)象的使用分離,將對(duì)象的創(chuàng)建交給專(zhuān)門(mén)的工廠類(lèi)負(fù)責(zé),但是其最大的缺點(diǎn)在于工廠類(lèi)不夠靈活,增加新的具體產(chǎn)品需要修改工廠類(lèi)的判斷邏輯代碼,而且產(chǎn)品較多時(shí),工廠方法代碼將會(huì)非常復(fù)雜。
2.工廠方法模式工廠方法模式:又稱(chēng)為工廠模式,也叫虛擬構(gòu)造器模式或者多態(tài)工廠模式它屬于類(lèi)創(chuàng)建型模式。在工廠方法模式中,工廠父類(lèi)負(fù)責(zé)定義創(chuàng)建產(chǎn)品對(duì)象的公共接口,而工廠子類(lèi)則負(fù)責(zé)生成具體的產(chǎn)品對(duì)象,這樣做的目的是將產(chǎn)品類(lèi)的實(shí)例化操作延遲到工廠子類(lèi)中完成,即通過(guò)工廠子類(lèi)來(lái)確定究竟應(yīng)該實(shí)例化哪一個(gè)具體產(chǎn)品類(lèi)這樣解釋可能會(huì)有點(diǎn)抽象。
// # 工廠方法模式 // 安全模式創(chuàng)建工廠類(lèi) var Ball = function (type,name) { /** * 安全模式 Ball也可以運(yùn)行處new Ball的效果 */ if(this instanceof Ball) { var s = new this[type](name); return s; }else { return new Ball(type,name); } } // 工廠原型中設(shè)置創(chuàng)建所有類(lèi)型數(shù)據(jù)對(duì)象的基類(lèi) Ball.prototype = { basketBall: function(name) { this.play = function() { console.log("我在打"+name); } }, footBall: function(name) { this.play = function() { console.log("我在踢"+name); } }, badmintonBall: function(name) { this.play = function() { console.log("我在打"+name); } }, // .... } var football = new Ball("footBall","足球"); football.play(); var basketball = new Ball("basketBall","籃球"); basketball.play(); var badmintonball = new Ball("badmintonBall","羽毛球"); badmintonball.play(); // # 工廠方法模式end
這段案例是這么去理解的,我們先創(chuàng)建一個(gè)球類(lèi)工廠,這個(gè)球類(lèi)工廠是一個(gè)抽象的,不做具體的實(shí)現(xiàn),然后我們?cè)谶@個(gè)球類(lèi)工廠里面在去定義對(duì)應(yīng)的球類(lèi)實(shí)現(xiàn),如籃球,羽毛球,足球等實(shí)現(xiàn),在工廠方法模式中,抽象類(lèi)工廠只是負(fù)責(zé)定義一個(gè)對(duì)外的公共接口,而工廠子類(lèi)則負(fù)責(zé)生成具體的產(chǎn)品對(duì)象。
這樣做的目的是將產(chǎn)品類(lèi)的實(shí)例化操作延遲到工廠子類(lèi)中完成,即通過(guò)工廠子類(lèi)來(lái)確定究竟應(yīng)該實(shí)例化哪一個(gè)具體產(chǎn)品類(lèi)如果這時(shí)候在出現(xiàn)一個(gè)新的球類(lèi)運(yùn)動(dòng),只需要為這種新類(lèi)型的球類(lèi)創(chuàng)建一個(gè)具體的球類(lèi)實(shí)現(xiàn)就可以,這一特點(diǎn)無(wú)疑使得工廠方法模式具有超越簡(jiǎn)單工廠模式的優(yōu)越性,更加符合“開(kāi)閉原則”
上面案例包含了一個(gè)安全模式的知識(shí)點(diǎn)
// 安全模式創(chuàng)建工廠類(lèi) var Ball = function (type,name) { /** * 安全模式 Ball也可以運(yùn)行處new Ball的效果 */ if(this instanceof Ball) { var s = new this[type](name); return s; }else { return new Ball(type,name); } }
這段代碼主要解決的問(wèn)題是,有些同學(xué)使用工廠類(lèi)的時(shí)候,忘記使用關(guān)鍵字new,得不到預(yù)期想要的效果這邊的解決方案就是,在構(gòu)造函數(shù)開(kāi)始時(shí)先判斷當(dāng)前對(duì)象this指代是不是當(dāng)前工廠類(lèi),如果不是則通過(guò)new關(guān)鍵字創(chuàng)建對(duì)象返回,這樣就可以實(shí)現(xiàn)不使用new關(guān)鍵詞也可以達(dá)到相同的效果了
工廠方法模式的優(yōu)點(diǎn):
在工廠方法模式中,工廠方法用來(lái)創(chuàng)建客戶(hù)所需要的產(chǎn)品,同時(shí)還向客戶(hù)隱藏了哪種具體產(chǎn)品類(lèi)將被實(shí)例化這一細(xì)節(jié),用戶(hù)只需要關(guān)心所需產(chǎn)品對(duì)應(yīng)的工廠,無(wú)須關(guān)心創(chuàng)建細(xì)節(jié),甚至無(wú)須知道具體產(chǎn)品類(lèi)的類(lèi)名。
基于工廠角色和產(chǎn)品角色的多態(tài)性設(shè)計(jì)是工廠方法模式的關(guān)鍵。它能夠使工廠可以自主確定創(chuàng)建何種產(chǎn)品對(duì)象,而如何創(chuàng)建這個(gè)對(duì)象的細(xì)節(jié)則完全封裝在具體工廠內(nèi)部。工廠方法模式之所以又被稱(chēng)為多態(tài)工廠模式,是因?yàn)樗械木唧w工廠類(lèi)都具有同一抽象父類(lèi)。
使用工廠方法模式的另一個(gè)優(yōu)點(diǎn)是在系統(tǒng)中加入新產(chǎn)品時(shí),無(wú)須修改抽象工廠和抽象產(chǎn)品提供的接口,無(wú)須修改客戶(hù)端,也無(wú)須修改其他的具體工廠和具體產(chǎn)品,而只要添加一個(gè)具體工廠和具體產(chǎn)品就可以了。這樣,系統(tǒng)的可擴(kuò)展性也就變得非常好,完全符合“開(kāi)閉原則”。
工廠方法模式的缺點(diǎn):
在添加新產(chǎn)品時(shí),需要編寫(xiě)新的具體產(chǎn)品類(lèi),而且還要提供與之對(duì)應(yīng)的具體工廠類(lèi),系統(tǒng)中類(lèi)的個(gè)數(shù)將成對(duì)增加,在一定程度上增加了系統(tǒng)的復(fù)雜度,有更多的類(lèi)需要編譯和運(yùn)行,會(huì)給系統(tǒng)帶來(lái)一些額外的開(kāi)銷(xiāo)。
由于考慮到系統(tǒng)的可擴(kuò)展性,需要引入抽象層,在客戶(hù)端代碼中均使用抽象層進(jìn)行定義,增加了系統(tǒng)的抽象性和理解難度
工廠方法模式的適用情況
在以下情況下可以使用工廠方法模式:
一個(gè)類(lèi)不知道它所需要的對(duì)象的類(lèi):在工廠方法模式中,客戶(hù)端不需要知道具體產(chǎn)品類(lèi)的類(lèi)名,只需要知道所對(duì)應(yīng)的工廠即可,具體的產(chǎn)品對(duì)象由具體工廠類(lèi)創(chuàng)建;客戶(hù)端需要知道創(chuàng)建具體產(chǎn)品的工廠類(lèi)。
一個(gè)類(lèi)通過(guò)其子類(lèi)來(lái)指定創(chuàng)建哪個(gè)對(duì)象:在工廠方法模式中,對(duì)于抽象工廠類(lèi)只需要提供一個(gè)創(chuàng)建產(chǎn)品的接口,而由其子類(lèi)來(lái)確定具體要?jiǎng)?chuàng)建的對(duì)象,利用面向?qū)ο蟮亩鄳B(tài)性和里氏代換原則,在程序運(yùn)行時(shí),子類(lèi)對(duì)象將覆蓋父類(lèi)對(duì)象,從而使得系統(tǒng)更容易擴(kuò)展。
將創(chuàng)建對(duì)象的任務(wù)委托給多個(gè)工廠子類(lèi)中的某一個(gè),客戶(hù)端在使用時(shí)可以無(wú)須關(guān)心是哪一個(gè)工廠子類(lèi)創(chuàng)建產(chǎn)品子類(lèi),需要時(shí)再動(dòng)態(tài)指定,可將具體工廠類(lèi)的類(lèi)名存儲(chǔ)在配置文件或數(shù)據(jù)庫(kù)中。
工廠方法模式總結(jié)
工廠方法模式是簡(jiǎn)單工廠模式的進(jìn)一步抽象和推廣。由于使用了面向?qū)ο蟮亩鄳B(tài)性,工廠方法模式保持了簡(jiǎn)單工廠模式的優(yōu)點(diǎn),而且克服了它的缺點(diǎn)。在工廠方法模式中,核心的工廠類(lèi)不再負(fù)責(zé)所有產(chǎn)品的創(chuàng)建,而是將具體創(chuàng)建工作交給子類(lèi)去做。這個(gè)核心類(lèi)僅僅負(fù)責(zé)給出具體工廠必須實(shí)現(xiàn)的接口,而不負(fù)責(zé)產(chǎn)品類(lèi)被實(shí)例化這種細(xì)節(jié),這使得工廠方法模式可以允許系統(tǒng)在不修改工廠角色的情況下引進(jìn)新產(chǎn)品。
工廠方法模式的主要優(yōu)點(diǎn)是增加新的產(chǎn)品類(lèi)時(shí)無(wú)須修改現(xiàn)有系統(tǒng),并封裝了產(chǎn)品對(duì)象的創(chuàng)建細(xì)節(jié),系統(tǒng)具有良好的靈活性和可擴(kuò)展性;其缺點(diǎn)在于增加新產(chǎn)品的同時(shí)需要增加新的工廠,導(dǎo)致系統(tǒng)類(lèi)的個(gè)數(shù)成對(duì)增加,在一定程度上增加了系統(tǒng)的復(fù)雜性。
抽象工廠模式:通過(guò)對(duì)類(lèi)的工廠抽象使其業(yè)務(wù)用于對(duì)產(chǎn)品類(lèi)簇的創(chuàng)建,而不是負(fù)責(zé)創(chuàng)建某一類(lèi)產(chǎn)品的實(shí)例,屬于對(duì)象創(chuàng)建型模式。
抽象類(lèi)一直出現(xiàn)在我們的文章中,那么這邊先來(lái)解釋一下什么是抽象類(lèi)
抽象類(lèi)是一種聲明但不能使用的類(lèi),當(dāng)你使用時(shí)就會(huì)報(bào)錯(cuò),在JavaScript中abstract還是一個(gè)保留字,所以目前來(lái)說(shuō)還不能像
傳統(tǒng)面向?qū)ο笳Z(yǔ)言那么輕松的去創(chuàng)建抽象類(lèi).
不過(guò)JavaScript有自己的實(shí)現(xiàn)方式,可以模擬出抽象類(lèi)
來(lái)一段代碼
// 抽象類(lèi)的介紹 var Ball = function () {} Ball.prototype = { play: function () { return new Error("抽象方法不能調(diào)用"); } }
解釋:
我們可以看到創(chuàng)建的Ball類(lèi)其實(shí)什么都不能做,創(chuàng)建時(shí)沒(méi)有任何屬性,原型定義的方法也不能使用,否則就會(huì)報(bào)錯(cuò)。但是在繼承上卻是很有用的,
因?yàn)槎x了一種類(lèi),并定義了該類(lèi)所具備的方法,如果沒(méi)有在子類(lèi)中重寫(xiě)這寫(xiě)方法,那么調(diào)用的時(shí)候就會(huì)報(bào)錯(cuò)。
這一特點(diǎn)可以很好的提醒子類(lèi)去重寫(xiě)這一方法,不然會(huì)在調(diào)用的時(shí)候提示錯(cuò)誤那么在了解了什么是抽象類(lèi)的情況下,我們?cè)趤?lái)比較一下工廠方法模式與抽象工廠模式的不同點(diǎn),以方便我們更好的去理解抽象工廠模式
工廠方法模式與抽象工廠模式的對(duì)比
在工廠方法模式中具體工廠負(fù)責(zé)生產(chǎn)具體的產(chǎn)品,每一個(gè)具體工廠對(duì)應(yīng)一種具體產(chǎn)品,工廠方法也具有唯一性,一般情況下,一個(gè)具體工廠中只有一個(gè)工廠方法或者一組重載的工廠方法。但是有時(shí)候我們需要一個(gè)工廠可以提供多個(gè)產(chǎn)品對(duì)象,而不是單一的產(chǎn)品對(duì)象。
為了更清晰地理解抽象工廠模式,需要先引入兩個(gè)概念:
產(chǎn)品等級(jí)結(jié)構(gòu) :產(chǎn)品等級(jí)結(jié)構(gòu)即產(chǎn)品的繼承結(jié)構(gòu),如一個(gè)抽象類(lèi)是電視機(jī),其子類(lèi)有海爾電視機(jī)、海信電視機(jī)、TCL電視機(jī),則抽象電視機(jī)與具體品牌的電視機(jī)之間構(gòu)成了一個(gè)產(chǎn)品等級(jí)結(jié)構(gòu),抽象電視機(jī)是父類(lèi),而具體品牌的電視機(jī)是其子類(lèi)。
產(chǎn)品族 :在抽象工廠模式中,產(chǎn)品族是指由同一個(gè)工廠生產(chǎn)的,位于不同產(chǎn)品等級(jí)結(jié)構(gòu)中的一組產(chǎn)品,如海爾電器工廠生產(chǎn)的
海爾電視機(jī)、海爾電冰箱,海爾電視機(jī)位于電視機(jī)產(chǎn)品等級(jí)結(jié)構(gòu)中,海爾電冰箱位于電冰箱產(chǎn)品等級(jí)結(jié)構(gòu)中。
抽象工廠模式與工廠方法模式最大的區(qū)別在于,工廠方法模式針對(duì)的是一個(gè)產(chǎn)品等級(jí)結(jié)構(gòu),而抽象工廠模式則需要面對(duì)多個(gè)產(chǎn)品等級(jí)結(jié)構(gòu),一個(gè)工廠等級(jí)結(jié)構(gòu)可以負(fù)責(zé)多個(gè)不同產(chǎn)品等級(jí)結(jié)構(gòu)中的產(chǎn)品對(duì)象的創(chuàng)建。當(dāng)一個(gè)工廠等級(jí)結(jié)構(gòu)可以創(chuàng)建出分屬于不同產(chǎn)品等級(jí)結(jié)構(gòu)的一個(gè)產(chǎn)品族中的所有對(duì)象時(shí),抽象工廠模式比工廠方法模式更為簡(jiǎn)單、有效率。
這句話比較簡(jiǎn)單的理解方式就是:如果一個(gè)工廠只需要生產(chǎn)一個(gè)類(lèi)型的產(chǎn)品比如說(shuō)電視機(jī),那么用工廠方法模式是比較合理的,如果這個(gè)工廠又需要成產(chǎn)電視機(jī),又需要生產(chǎn)冰箱之類(lèi)的,那么這時(shí)候用工廠抽象模式就是最合適的。
// # 抽象工廠模式 var Sport = function(subType, superType) { if( typeof Sport[superType] === "function"){ // 緩存類(lèi) function F() {}; // 繼承父類(lèi)屬性和方法 F.prototype = new Sport[superType](); // 將子類(lèi)constructor 指向子類(lèi) subType.constructor = subType; // 子類(lèi)原型繼承 “父類(lèi)” subType.prototype = new F(); }else { // 不存在抽象類(lèi)則拋出錯(cuò)誤 throw new Error("未創(chuàng)建該抽象類(lèi)"); } } // 球類(lèi)運(yùn)動(dòng)抽象類(lèi) Sport.Ball = function () { this.type = "ball"; } Sport.Ball.prototype = { play: function () { return new Error("抽象方法不能調(diào)用"); } } // 力量型運(yùn)動(dòng)抽象類(lèi) Sport.Power = function () { this.type = "power"; } Sport.Power.prototype = { play: function () { return new Error("抽象方法不能調(diào)用"); } } // 速度型運(yùn)動(dòng)抽象類(lèi) Sport.Speed = function () { this.type = "speed"; } Sport.Speed.prototype = { play: function () { return new Error("抽象方法不能調(diào)用"); } } // 籃球類(lèi) var BasketBall = function (name) { this.name = name; }; // 抽象工廠實(shí)現(xiàn)對(duì)球類(lèi)運(yùn)動(dòng)的繼承 Sport(BasketBall,"Ball"); BasketBall.prototype.play = function () { console.log("我在玩"+this.name); } // 舉重類(lèi) var WeightLifting = function (name) { this.name = name; }; // 抽象工廠實(shí)現(xiàn)對(duì)力量型運(yùn)動(dòng)的繼承 Sport(WeightLifting,"Power"); WeightLifting.prototype.play = function () { console.log("我在玩"+this.name); } // 跑步類(lèi) var Running = function (name) { this.name = name; }; // 抽象工廠實(shí)現(xiàn)對(duì)速度運(yùn)動(dòng)的繼承 Sport(Running,"Speed"); Running.prototype.play = function () { console.log("我在"+this.name); } // 抽象工廠模式實(shí)現(xiàn) var basketBall = new BasketBall("籃球"); console.log(basketBall.type);//ball basketBall.play(); var weightLifting = new WeightLifting("舉重"); console.log(weightLifting.type);//power weightLifting.play(); var running = new Running("跑步"); console.log(running.type);//ball running.play(); /** 輸出結(jié)果 * ball * 我在玩籃球 * power * 我在玩舉重 * speed * 我在跑步 */ // # 抽象工廠模式end
這段栗子先是創(chuàng)建一個(gè)運(yùn)動(dòng)類(lèi)的抽象工廠,通過(guò)這個(gè)暴露外部調(diào)用的接口,傳遞2個(gè)參數(shù),一個(gè)是subType,當(dāng)前實(shí)例化的對(duì)象,也就是子類(lèi),
一個(gè)是superType,需要繼承的父類(lèi)(抽象類(lèi))的名稱(chēng),在工廠函數(shù)中實(shí)現(xiàn)了子類(lèi)對(duì)父類(lèi)的繼承。
在繼承過(guò)程中有一個(gè)地方需要注意,就是在對(duì)過(guò)渡類(lèi)繼承的時(shí)候,我們不是繼承父類(lèi)原型,而是通過(guò)new關(guān)鍵字復(fù)制父類(lèi)的一個(gè)實(shí)列,這樣做的目的是過(guò)渡類(lèi)不僅僅繼承父類(lèi)的原型方法,還需要繼承父類(lèi)的對(duì)象屬性,所以通過(guò)new關(guān)鍵字的方式實(shí)現(xiàn)了繼承。
然后通過(guò)在抽象工廠類(lèi)上面進(jìn)行擴(kuò)展對(duì)應(yīng)的抽象類(lèi),也就是我們需要通過(guò)繼承的父類(lèi),我這邊添加了3個(gè)抽象類(lèi)Ball,Power,Speed,分別給抽象類(lèi)指定了type屬性,還有方法play,既然創(chuàng)建了抽象類(lèi),那么下面就是開(kāi)始使用抽象工廠去創(chuàng)建子類(lèi),這邊分別對(duì)Ball,Power,Speed 3個(gè)抽象類(lèi)進(jìn)行了實(shí)現(xiàn)創(chuàng)建了BasketBall(球類(lèi)),WeightLifting(力量),Running(速度)3個(gè)子類(lèi)3個(gè)子類(lèi)分別對(duì)play方法進(jìn)行了實(shí)現(xiàn)最后就是對(duì)于子類(lèi)的調(diào)用實(shí)現(xiàn),在實(shí)現(xiàn)子類(lèi)調(diào)用的時(shí)候,
我們可以獲取到繼承的父類(lèi)當(dāng)中對(duì)應(yīng)的type
抽象工廠模式的優(yōu)點(diǎn):
當(dāng)一個(gè)產(chǎn)品族中的多個(gè)對(duì)象被設(shè)計(jì)成一起工作時(shí),它能夠保證客戶(hù)端始終只使用同一個(gè)產(chǎn)品族中的對(duì)象。
增加新的具體工廠和產(chǎn)品族很方便,無(wú)須修改已有系統(tǒng),符合“開(kāi)閉原則”。
抽象工廠模式的缺點(diǎn):
開(kāi)閉原則的傾斜性(增加新的工廠和產(chǎn)品族容易,增加新的產(chǎn)品等級(jí)結(jié)構(gòu)麻煩)。
增加新的產(chǎn)品等級(jí)結(jié)構(gòu):對(duì)于增加新的產(chǎn)品等級(jí)結(jié)構(gòu),需要修改所有的工廠角色,包括抽象工廠類(lèi),在所有的工廠類(lèi)中都需要增加生產(chǎn)新產(chǎn)品的方法,不能很好地支持“開(kāi)閉原則”。
抽象工廠模式的適用情況:
在以下情況下可以使用抽象工廠模式:
一個(gè)系統(tǒng)不應(yīng)當(dāng)依賴(lài)于產(chǎn)品類(lèi)實(shí)例如何被創(chuàng)建、組合和表達(dá)的細(xì)節(jié),這對(duì)于所有類(lèi)型的工廠模式都是重要的。
系統(tǒng)中有多于一個(gè)的產(chǎn)品族,而每次只使用其中某一產(chǎn)品族。屬于同一個(gè)產(chǎn)品族的產(chǎn)品將在一起使用,這一約束必須在系統(tǒng)的設(shè)計(jì)中體現(xiàn)出來(lái)。
系統(tǒng)提供一個(gè)產(chǎn)品類(lèi)的庫(kù),所有的產(chǎn)品以同樣的接口出現(xiàn),從而使客戶(hù)端不依賴(lài)于具體實(shí)現(xiàn)。
抽象工廠模式總結(jié)
抽象工廠模式是所有形式的工廠模式中最為抽象和最具一般性的一種形態(tài)。抽象工廠模式與工廠方法模式最大的區(qū)別在于,工廠方法模式針對(duì)的是一個(gè)產(chǎn)品等級(jí)結(jié)構(gòu),而抽象工廠模式則需要面對(duì)多個(gè)產(chǎn)品等級(jí)結(jié)構(gòu)。
抽象工廠模式適用情況包括:一個(gè)系統(tǒng)不應(yīng)當(dāng)依賴(lài)于產(chǎn)品類(lèi)實(shí)例如何被創(chuàng)建、組合和表達(dá)的細(xì)節(jié);系統(tǒng)中有多于一個(gè)的產(chǎn)品族,而每次只使用其中某一產(chǎn)品族;屬于同一個(gè)產(chǎn)品族的產(chǎn)品將在一起使用;系統(tǒng)提供一個(gè)產(chǎn)品類(lèi)的庫(kù),所有的產(chǎn)品以同樣的接口出現(xiàn),從而使客戶(hù)端不依賴(lài)于具體實(shí)現(xiàn)。
4.三大工廠模式的關(guān)聯(lián)性當(dāng)抽象工廠模式中每一個(gè)具體工廠類(lèi)只創(chuàng)建一個(gè)產(chǎn)品對(duì)象,也就是只存在一個(gè)產(chǎn)品等級(jí)結(jié)構(gòu)時(shí),抽象工廠模式轉(zhuǎn)換成工廠方法模式;
當(dāng)工廠方法模式中抽象工廠與具體工廠合并,提供一個(gè)統(tǒng)一的工廠來(lái)創(chuàng)建產(chǎn)品對(duì)象,并將創(chuàng)建對(duì)象的工廠方法設(shè)計(jì)為靜態(tài)方法時(shí),工廠方法模式退化成簡(jiǎn)單工廠模式。
注:根據(jù)實(shí)際適用情況去選擇對(duì)應(yīng)的工廠模式
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://specialneedsforspecialkids.com/yun/90572.html
摘要:設(shè)計(jì)模式工廠模式最近閱讀了幾本設(shè)計(jì)模式方面的書(shū)籍學(xué)習(xí)之余整理下來(lái)方便以后的歸納和梳理設(shè)計(jì)模式工廠模式創(chuàng)造工廠模式是一種創(chuàng)建性模式也就是一種創(chuàng)建對(duì)象的最佳實(shí)踐首先我們需要理解為什么我們需要工廠模式想象一個(gè)場(chǎng)景如果你要求去買(mǎi)一些東西板燒雞腿 Javascript設(shè)計(jì)模式-工廠模式 最近閱讀了幾本設(shè)計(jì)模式方面的書(shū)籍,學(xué)習(xí)之余整理下來(lái),方便以后的歸納和梳理 設(shè)計(jì)模式-工廠模式 創(chuàng)造工廠模式是一...
摘要:從設(shè)計(jì)模式的分類(lèi)來(lái)看簡(jiǎn)單工廠模式是創(chuàng)建型模式。使用簡(jiǎn)單工廠模式將會(huì)增加系統(tǒng)中類(lèi)的個(gè)數(shù),在一定程序上增加了系統(tǒng)的復(fù)雜度和理解難度。簡(jiǎn)單工廠模式由于使用了靜態(tài)工廠方法,造成工廠角色無(wú)法形成基于繼承的等級(jí)結(jié)構(gòu)。 簡(jiǎn)單工廠模式提供了一個(gè)接口可以根據(jù)傳遞的參數(shù)的不同創(chuàng)建不同的對(duì)象,從而將對(duì)象自身的邏輯與對(duì)象的創(chuàng)建分離開(kāi)。 從設(shè)計(jì)模式的分類(lèi)來(lái)看簡(jiǎn)單工廠模式是創(chuàng)建型模式。事實(shí)上與簡(jiǎn)單工廠模式類(lèi)似的還...
摘要:工廠方法模式,通過(guò)對(duì)產(chǎn)品類(lèi)的抽象使其創(chuàng)建業(yè)務(wù),主要負(fù)責(zé)創(chuàng)建多類(lèi)產(chǎn)品的實(shí)例。安全模式類(lèi)安全模式類(lèi)可以屏蔽使用類(lèi)的錯(cuò)誤造成的錯(cuò)誤。可以將工廠方法看作是一個(gè)實(shí)例化對(duì)象的工廠類(lèi),安全起見(jiàn),采用安全模式類(lèi),將創(chuàng)建對(duì)象的基類(lèi)放在工廠方法類(lèi)的原型中即可。 工廠方法模式,通過(guò)對(duì)產(chǎn)品類(lèi)的抽象使其創(chuàng)建業(yè)務(wù),主要負(fù)責(zé)創(chuàng)建多類(lèi)產(chǎn)品的實(shí)例。前面記錄了簡(jiǎn)單工廠模式,但是需求時(shí)不斷變化的,當(dāng)需求簡(jiǎn)單時(shí),直接創(chuàng)建對(duì)象...
摘要:設(shè)計(jì)模式共有種,我今天先來(lái)了解一下工廠模式,其他的模式將會(huì)在后續(xù)的博客中陸續(xù)為大家講解。工廠模式主要分為簡(jiǎn)單工廠模式和抽象工廠模式。抽象工廠模式抽象工廠模式與簡(jiǎn)單工廠函數(shù)不同的是,抽象工廠函數(shù)會(huì)先設(shè)計(jì)好接口,具體的實(shí)現(xiàn)在子類(lèi)中進(jìn)行。 設(shè)計(jì)模式 設(shè)計(jì)模式(design pattern)概念:是一套反復(fù)使用、思想成熟、經(jīng)過(guò)分類(lèi)和無(wú)數(shù)實(shí)戰(zhàn)設(shè)計(jì)經(jīng)驗(yàn)的總結(jié)。是為了代碼可重用、可擴(kuò)展、可解耦、更容...
摘要:都是構(gòu)造函數(shù)模式創(chuàng)建的原生構(gòu)造函數(shù)。使用構(gòu)造函數(shù)創(chuàng)建對(duì)象經(jīng)歷了以下四個(gè)過(guò)程創(chuàng)建一個(gè)新對(duì)象構(gòu)造函數(shù)的作用域交給新對(duì)象。 ??在創(chuàng)建對(duì)象的時(shí)候,使用對(duì)象字面量和 new Object() 構(gòu)造函數(shù)的方式創(chuàng)建一個(gè)對(duì)象是最簡(jiǎn)單最方便的方式。但是凡是處于初級(jí)階段的事物都會(huì)不可避免的存在一個(gè)問(wèn)題,沒(méi)有普適性,意思就是說(shuō)我要為世界上(程序中)的所有使用到的對(duì)象都使用一遍 var xxx = {} ,...
摘要:都是構(gòu)造函數(shù)模式創(chuàng)建的原生構(gòu)造函數(shù)。使用構(gòu)造函數(shù)創(chuàng)建對(duì)象經(jīng)歷了以下四個(gè)過(guò)程創(chuàng)建一個(gè)新對(duì)象構(gòu)造函數(shù)的作用域交給新對(duì)象。 ??在創(chuàng)建對(duì)象的時(shí)候,使用對(duì)象字面量和 new Object() 構(gòu)造函數(shù)的方式創(chuàng)建一個(gè)對(duì)象是最簡(jiǎn)單最方便的方式。但是凡是處于初級(jí)階段的事物都會(huì)不可避免的存在一個(gè)問(wèn)題,沒(méi)有普適性,意思就是說(shuō)我要為世界上(程序中)的所有使用到的對(duì)象都使用一遍 var xxx = {} ,...
閱讀 3470·2021-09-22 15:02
閱讀 3507·2021-09-02 15:21
閱讀 2133·2019-08-30 15:55
閱讀 2780·2019-08-30 15:44
閱讀 776·2019-08-29 16:56
閱讀 2414·2019-08-23 18:22
閱讀 3342·2019-08-23 12:20
閱讀 3091·2019-08-23 11:28