分享JavaScript的?3?種工廠(chǎng)模式的用法
前言;
工廠(chǎng)模式(Factory Pattern)是設(shè)計(jì)模式中最常用的設(shè)計(jì)模式之一。
這種類(lèi)型的設(shè)計(jì)模式屬于創(chuàng)建型模式,它提供了一種創(chuàng)建對(duì)象的最佳方式。
在工廠(chǎng)模式中,我們?cè)趧?chuàng)建對(duì)象時(shí)不會(huì)對(duì)客戶(hù)端暴露創(chuàng)建邏輯,并且是通過(guò)使用一個(gè)共同的接口來(lái)指向新創(chuàng)建的對(duì)象。
工廠(chǎng)模式分為:
- 簡(jiǎn)單工廠(chǎng)模式
- 工廠(chǎng)方法模式
- 抽象工廠(chǎng)模式
一、簡(jiǎn)單工廠(chǎng)模式
簡(jiǎn)單工廠(chǎng)模式,也可以叫靜態(tài)工廠(chǎng)模式,用一個(gè)工廠(chǎng)對(duì)象創(chuàng)建同一類(lèi)對(duì)象類(lèi)的實(shí)例。
比如:
// 0.0.2/es5.simple.factory.js function Role(options){ this.role = options.role; this.permissions = options.permissions; } Role.prototype.show = function (){ var str = '是一個(gè)' + this.role + ', 權(quán)限:' + this.permissions.join(', '); console.log(str) } function simpleFactory(role){ switch(role) { case 'admin': return new Role({ role: '管理員', permissions: ['設(shè)置', '刪除', '新增', '創(chuàng)建', '開(kāi)發(fā)', '推送', '提問(wèn)', '評(píng)論'] }); break; case 'developer': return new Role({ role: '開(kāi)發(fā)者', permissions: ['開(kāi)發(fā)', '推送', '提問(wèn)', '評(píng)論'] }); break; default: throw new Error('參數(shù)只能為 admin 或 developer'); } } // 實(shí)例 const xm = simpleFactory('admin'); xm.show(); const xh = simpleFactory('developer'); xh.show(); const xl = simpleFactory('guest'); xl.show();
ES6 寫(xiě)法:
// 0.0.2/simple.factory.js class SimpleFactory { constructor(opt) { this.role = opt.role; this.permissions = opt.permissions; } // 靜態(tài)方法 static create(role) { switch (role) { case 'admin': return new SimpleFactory({ role: '管理員', permissions: ['設(shè)置', '刪除', '新增', '創(chuàng)建', '開(kāi)發(fā)', '推送', '提問(wèn)', '評(píng)論'] }); break; case 'developer': return new SimpleFactory({ role: '開(kāi)發(fā)者', permissions: ['開(kāi)發(fā)', '推送', '提問(wèn)', '評(píng)論'] }); break; default: throw new Error('參數(shù)只能為 admin 或 developer'); } } show() { const str = `是一個(gè)${this.role}, 權(quán)限:${this.permissions.join(', ')}`; console.log(str); } } // 實(shí)例 const xm = SampleFactory.create('admin'); xm.show(); const xh = SampleFactory.create('developer'); xh.show(); const xl = SampleFactory.create('guest'); xl.show();
上例中,??simpleFactory?
??就是一個(gè)簡(jiǎn)單工廠(chǎng),2個(gè)實(shí)例對(duì)應(yīng)不同的權(quán)限,調(diào)用工廠(chǎng)函數(shù)時(shí),只需傳遞 ??admin?
?? 或 ??developer?
? 就可獲取對(duì)應(yīng)的實(shí)例對(duì)象。
注意:作為一種創(chuàng)建類(lèi)模式,在任何需要生成復(fù)雜對(duì)象的地方,都可以使用工廠(chǎng)方法模式。有一點(diǎn)需要注意的地方就是復(fù)雜對(duì)象適合使用工廠(chǎng)模式,而簡(jiǎn)單對(duì)象,特別是只需要通過(guò) new 就可以完成創(chuàng)建的對(duì)象,無(wú)需使用工廠(chǎng)模式。如果使用工廠(chǎng)模式,就需要引入一個(gè)工廠(chǎng)類(lèi),會(huì)增加系統(tǒng)的復(fù)雜度。
二、工廠(chǎng)方法模式
將實(shí)際創(chuàng)建對(duì)象工作推遲到子類(lèi)當(dāng)中,核心類(lèi)就成了抽象類(lèi)。
這樣添加新的類(lèi)時(shí)就無(wú)需修改工廠(chǎng)方法,只需要將子類(lèi)注冊(cè)進(jìn)工廠(chǎng)方法的原型對(duì)象中即可。
比如:
// 0.0.2/es5.function.factory.js function FunctionFactory(role) { if(!(['admin', 'developer'].indexOf(role) > -1)){ throw new Error('參數(shù)只能為 admin 或 developer'); } // 安全的工廠(chǎng)方法 if (this instanceof FunctionFactory) { return this[role](); } return new FunctionFactory(role); } FunctionFactory.prototype.show = function () { var str = '是一個(gè)' + this.role + ', 權(quán)限:' + this.permissions.join(', '); console.log(str) } FunctionFactory.prototype.admin = function (permissions) { this.role = '管理員'; this.permissions = ['設(shè)置', '刪除', '新增', '創(chuàng)建', '開(kāi)發(fā)', '推送', '提問(wèn)', '評(píng)論']; } FunctionFactory.prototype.developer = function (permissions) { this.role = '開(kāi)發(fā)者'; this.permissions = ['開(kāi)發(fā)', '推送', '提問(wèn)', '評(píng)論']; } var xm = FunctionFactory('admin'); xm.show(); var xh = FunctionFactory('developer'); xh.show(); var xl = FunctionFactory('guest'); xl.show();
當(dāng)需要添加新類(lèi)時(shí),只需掛載在 ??FunctionFactory.prototype?
?
上,無(wú)需修改工廠(chǎng)方法,也實(shí)現(xiàn)了 OCP 原則。
OCP
(Open-Closed Principle,開(kāi)放-封閉原則)由Bertrand Meyer在1988年提出,含義是“軟件實(shí)體( 類(lèi)、模塊、函數(shù)等 )應(yīng)該是可擴(kuò)展的,但不可修改”。
- 可擴(kuò)展(Open for extension,即“對(duì)于擴(kuò)展是開(kāi)放的”) 意思是軟件模塊的行為(功能)可以變化、可以擴(kuò)展。
- 不可修改(Closed for modifications,即“對(duì)于修改是封閉的”) 意思是在擴(kuò)展新功能時(shí),不需要修改原有代碼模塊,而是另外增加一些新的代碼。
三、抽象工廠(chǎng)模式
抽象工廠(chǎng)模式(Abstract Factory Pattern)是圍繞一個(gè)超級(jí)工廠(chǎng)創(chuàng)建其他工廠(chǎng)。該超級(jí)工廠(chǎng)又稱(chēng)為其他工廠(chǎng)的工廠(chǎng)。這種類(lèi)型的設(shè)計(jì)模式屬于創(chuàng)建型模式,它提供了一種創(chuàng)建對(duì)象的最佳方式。
抽象工廠(chǎng)只留對(duì)外的口子,不做事,留給外界覆蓋(子類(lèi)重寫(xiě)接口方法以便創(chuàng)建的時(shí)候指定自己的對(duì)象類(lèi)型)。主要用于對(duì) 產(chǎn)品類(lèi)簇
的創(chuàng)建,不直接生成實(shí)例(簡(jiǎn)單工廠(chǎng)模式和工廠(chǎng)方法模式都是生成實(shí)例)。
比如 Jquery:
// 0.0.2/jquery.factory.js // 工廠(chǎng)模式 class jQuery { constructor(selector) { let slice = Array.prototype.slice; let dom = slice.call(document.querySelectorAll(selector)); let len = dom ? dom.length : 0; for (let i = 0; i < len; i++) { this[i] = dom[i]; } this.length = len this.selector = selector || '' } addClass(name) { console.log(name) } html(data) { } // 省略多個(gè) API } // 工廠(chǎng)模式 window.$ = function(selector) { return new jQuery(selector); } // 實(shí)例 const $li = $('li') $li.addClass('item');
四、小結(jié)
用大白話(huà)解釋?zhuān)?/strong>
簡(jiǎn)單工廠(chǎng)模式就是你給工廠(chǎng)什么,工廠(chǎng)就給你生產(chǎn)什么;
工廠(chǎng)方法模式就是你找工廠(chǎng)生產(chǎn)產(chǎn)品,工廠(chǎng)是外包給下級(jí)分工廠(chǎng)來(lái)代加工,需要先評(píng)估一下能不能代加工;能做就接,不能做就找其他工廠(chǎng);
抽象工廠(chǎng)模式就是工廠(chǎng)接了某項(xiàng)產(chǎn)品訂單但是做不了,上級(jí)集團(tuán)公司新建一個(gè)工廠(chǎng)來(lái)專(zhuān)門(mén)代加工某項(xiàng)產(chǎn)品;
再實(shí)在一點(diǎn)的解釋?zhuān)?/strong>
簡(jiǎn)單工廠(chǎng)模式,就是你去線(xiàn)下小賣(mài)部買(mǎi)東西,你要罐頭這個(gè)商品,它就會(huì)把擁有罐頭屬性的東西給你;
工廠(chǎng)方法模式,就是你去網(wǎng)購(gòu),你要罐頭,首先網(wǎng)店會(huì)判斷自己店里有沒(méi)有這個(gè)東西,如果沒(méi)有,就去進(jìn)貨;但是注意的是,它進(jìn)貨也并不是先進(jìn)到店里再發(fā)給你,而是直接從進(jìn)貨的子工廠(chǎng)發(fā)給你;
抽象工廠(chǎng)模式,即:做出像淘寶、京東、拼夕夕這樣的工廠(chǎng),是一個(gè)更高級(jí)別的構(gòu)建,你再去其中買(mǎi)罐頭;
到此這篇關(guān)于分享JavaScript的 3 種工廠(chǎng)模式的用法的文章就介紹到這了,更多相關(guān)JS工廠(chǎng)模式內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
JS基于遞歸算法實(shí)現(xiàn)1,2,3,4,5,6,7,8,9倒序放入數(shù)組中的方法
這篇文章主要介紹了JS基于遞歸算法實(shí)現(xiàn)1,2,3,4,5,6,7,8,9倒序放入數(shù)組中的方法,涉及JS遞歸算法操作數(shù)組實(shí)現(xiàn)排序功能的相關(guān)技巧,需要的朋友可以參考下2017-01-01原生javascript移動(dòng)端滑動(dòng)banner效果
這篇文章主要為大家詳細(xì)介紹了原生javascript移動(dòng)端滑動(dòng)banner效果,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-03-03js實(shí)現(xiàn)電梯導(dǎo)航效果的示例代碼
這篇文章主要介紹了JavaScript實(shí)現(xiàn)電梯導(dǎo)航效果的相關(guān)知識(shí),文中通過(guò)示例代碼介紹的很詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)吧2023-12-12淺談 Webpack 如何處理圖片(開(kāi)發(fā)、打包、優(yōu)化)
這篇文章主要介紹了淺談 Webpack 如何處理圖片(開(kāi)發(fā)、打包、優(yōu)化),小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2019-05-05textarea焦點(diǎn)的用法實(shí)現(xiàn)獲取焦點(diǎn)清空失去焦點(diǎn)提示效果
這篇文章主要介紹了textarea焦點(diǎn)的用法實(shí)現(xiàn)獲取焦點(diǎn)清空失去焦點(diǎn)提示效果,需要的朋友可以參考下2014-05-05利用js實(shí)現(xiàn)Vue2.0中數(shù)據(jù)的雙向綁定功能
vue數(shù)據(jù)雙向綁定是通過(guò)數(shù)據(jù)劫持結(jié)合發(fā)布者-訂閱者模式的方式來(lái)實(shí)現(xiàn)的,下面這篇文章主要給大家介紹了關(guān)于如何利用js實(shí)現(xiàn)Vue2.0中數(shù)據(jù)的雙向綁定功能的相關(guān)資料,需要的朋友可以參考下2021-07-07javascript或asp實(shí)現(xiàn)的判斷身份證號(hào)碼是否正確兩種驗(yàn)證方法
在網(wǎng)頁(yè)中經(jīng)常需要輸入正確的身份證號(hào)碼,只能通過(guò)程序來(lái)驗(yàn)證身份證格式。根據(jù)身份證號(hào)碼生成的原理,就是驗(yàn)證后面幾位就可以了。2009-11-11