javascript設(shè)計(jì)模式 – 簡(jiǎn)單工廠模式原理與應(yīng)用實(shí)例分析
本文實(shí)例講述了javascript設(shè)計(jì)模式 – 簡(jiǎn)單工廠模式。分享給大家供大家參考,具體如下:
介紹:簡(jiǎn)單工廠模式是最常用的一類創(chuàng)建型設(shè)計(jì)模式。其中簡(jiǎn)單工廠模式并不屬于GoF23個(gè)經(jīng)典設(shè)計(jì)模式,它通常被作為學(xué)習(xí)其他工廠模式的基礎(chǔ)。
定義:定義一個(gè)工廠類,它可以根據(jù)參數(shù)的不同返回不同的實(shí)例,被創(chuàng)建的實(shí)例通常都具有相同的父類,因?yàn)樵诤?jiǎn)單工廠模式中創(chuàng)建實(shí)例的方法是靜態(tài)方法,因此簡(jiǎn)單工廠模式又被稱為靜態(tài)工廠方法模式,它屬于類創(chuàng)建型模式。
場(chǎng)景:我們需要寫(xiě)一個(gè)dialog工具類,在項(xiàng)目初期我們只需要考慮一個(gè)簡(jiǎn)單的彈窗實(shí)現(xiàn),項(xiàng)目持續(xù)迭代,會(huì)衍生出各種類型的彈窗,帶關(guān)閉按鈕的,帶確認(rèn)按鈕的…..
我見(jiàn)到最多的做法是根據(jù)一個(gè)type值來(lái)判斷當(dāng)前需要彈什么類型的窗口,這樣的設(shè)計(jì)我之前沒(méi)覺(jué)得有問(wèn)題,但是看了前面介紹的設(shè)計(jì)原則,我們也來(lái)分析下這么做的缺點(diǎn):
1. 存在多個(gè)if…else…代碼塊,代碼冗長(zhǎng),閱讀困難,維護(hù)困難,測(cè)試?yán)щy,影響系統(tǒng)性能。
2. dialog類職責(zé)過(guò)重,負(fù)責(zé)初始化所有彈窗實(shí)例,違反了單一職責(zé)原則,不利于重用和維護(hù)。
3. 當(dāng)需要新增彈窗類型是,必須修改源代碼,違反了開(kāi)關(guān)原則。
4. 不同種類彈窗基礎(chǔ)樣式相同,會(huì)導(dǎo)致存在大量重復(fù)代碼。
5. 各類彈窗的創(chuàng)建和使用都是在各個(gè)業(yè)務(wù)邏輯中,如果我想修改創(chuàng)建方式必須修改所有業(yè)務(wù)代碼,違反了開(kāi)關(guān)原則
示例:
var Dialog = (function(){ var createNotice = function(){ return '<div>notice</div>'; } var createToast = function(){ return '<div>toast</div>'; } var createWarnin = function(){ return '<div>warnin</div>'; } var Dialog = function(){ this.element = ''; this.name = ''; this.show = function(){ console.log(this.name + ' is show -> ' + this.element); }; } return { factory: function(arg){ var _dialog; if(arg === 'notice'){ _dialog = new Dialog(); _dialog.element = createNotice(); _dialog.name = 'notice'; }else if(arg === 'toast'){ _dialog = new Dialog(); _dialog.element = createToast(); _dialog.name = 'toast'; }else if(arg === 'warnin'){ _dialog = new Dialog(); _dialog.element = createWarnin(); _dialog.name = 'warnin'; } return _dialog; } } })(); var notice = Dialog.factory('notice'); var toast = Dialog.factory('toast'); var warnin = Dialog.factory('warnin'); toast.show(); //toast is show -> <div>toast</div> notice.show(); //notice is show -> <div>notice</div> warnin.show(); //warnin is show -> <div>warnin</div>
以上的解決方案是自己理解著寫(xiě)的,對(duì)照著java的示例寫(xiě)了一個(gè),實(shí)現(xiàn)的方式有很多種,你可以用原型鏈,用繼承來(lái)實(shí)現(xiàn)都可以。我們這里主要討論下為什么要這么寫(xiě)。
之前我們列出了5個(gè)缺點(diǎn):我們主要解決了2,4和5,將共有的方法屬性抽取出來(lái)寫(xiě)在父類上,減少了重復(fù)代碼,將每種情況特有的代碼抽取出來(lái),解決了不符合單一職責(zé)原則的問(wèn)題。
重要的是將所有彈窗的創(chuàng)建集中在工廠類中,當(dāng)有修改時(shí),只需要修改工廠類即可,不會(huì)影響業(yè)務(wù)代碼。
這里我們思考一下:1.如何去掉那些if…else…? 2.當(dāng)我要新增一個(gè)error類型的彈窗時(shí)如何滿足開(kāi)關(guān)原則?
我自己試了一下:
var Dialog = function(){ this.element = ''; this.name = ''; this.show = function(){ console.log(this.name + ' is show -> ' + this.element); }; } Dialog.createNotice = function(){ return '<div>notice</div>'; }; Dialog.createToast = function(){ return '<div>toast</div>'; }; Dialog.createWarnin = function(){ return '<div>warnin</div>'; }; Dialog.factory = function(arg){ var _dialog = new Dialog(); _dialog.element = Dialog[arg](); _dialog.name = arg; return _dialog; }; var notice = Dialog.factory('createNotice'); var toast = Dialog.factory('createToast'); var warnin = Dialog.factory('createWarnin'); notice.show(); //createNotice is show -> <div>notice</div> warnin.show(); //createWarnin is show -> <div>warnin</div> toast.show(); //createToast is show -> <div>toast</div>
這樣當(dāng)我做新增時(shí),只需要要新增一條配置即可,不用去對(duì)公告內(nèi)容做修改。滿足了開(kāi)關(guān)原則的對(duì)擴(kuò)展支持對(duì)修改關(guān)閉。
簡(jiǎn)單工廠模式總結(jié):
優(yōu)點(diǎn):
* 簡(jiǎn)單工廠模式實(shí)現(xiàn)了對(duì)象創(chuàng)建和使用的分離
缺點(diǎn):
* 工廠模式集中了所有產(chǎn)品的創(chuàng)建邏輯,職責(zé)過(guò)重,一旦出現(xiàn)問(wèn)題會(huì)影響到整個(gè)系統(tǒng)
適用場(chǎng)景:
* 適用于創(chuàng)建的對(duì)象比較少,由于創(chuàng)建的對(duì)象較少,不會(huì)造成工廠方法中的業(yè)務(wù)邏輯太過(guò)復(fù)雜
* 客戶端只知道傳入工廠類的參數(shù),對(duì)于如何創(chuàng)建對(duì)象并不關(guān)心
感興趣的朋友可以使用在線HTML/CSS/JavaScript代碼運(yùn)行工具:http://tools.jb51.net/code/HtmlJsRun測(cè)試上述代碼運(yùn)行效果。
更多關(guān)于JavaScript相關(guān)內(nèi)容感興趣的讀者可查看本站專題:《javascript面向?qū)ο笕腴T教程》、《JavaScript錯(cuò)誤與調(diào)試技巧總結(jié)》、《JavaScript數(shù)據(jù)結(jié)構(gòu)與算法技巧總結(jié)》、《JavaScript遍歷算法與技巧總結(jié)》及《JavaScript數(shù)學(xué)運(yùn)算用法總結(jié)》
希望本文所述對(duì)大家JavaScript程序設(shè)計(jì)有所幫助。
相關(guān)文章
使用JS判斷是否數(shù)字和小數(shù)點(diǎn)組合的數(shù)字的兩中方法比較(isNaN和逐判斷)
使用js判斷數(shù)字和小數(shù)點(diǎn)的方法非常之多。但是就目前而言,我見(jiàn)過(guò)最好用的判斷方法應(yīng)該來(lái)說(shuō)是isNaN,它比較方便,而逐個(gè)比較的方法有一定的弊端。2009-09-09仿163填寫(xiě)郵件地址自動(dòng)顯示下拉(無(wú)優(yōu)化)
本框內(nèi)填個(gè)1,這些值都寫(xiě)在隱藏域了。代碼里可以看到,用戶輸入包含在里面的時(shí)候,可以按ENTER鍵選中.2008-11-11javascript用戶注冊(cè)提示效果的簡(jiǎn)單實(shí)例
這個(gè)可以增加用戶驗(yàn)證,不用js alert來(lái)作提示,而是在右邊提示,現(xiàn)在很多網(wǎng)站都這樣做,有需要的朋友可以參考一下2013-08-08css+js制作不定高度展開(kāi)收起動(dòng)畫(huà)詳解
這篇文章主要介紹了css+js制作不定高度展開(kāi)收起動(dòng)畫(huà)詳解的相關(guān)資料,需要的朋友可以參考下2023-06-06動(dòng)態(tài)加載js文件 document.createElement
動(dòng)態(tài)加載js文件 document.createElement...2006-10-10js實(shí)現(xiàn)顏色階梯漸變效果(Gradient算法)
在色彩中,色相、明度、純度也都可以產(chǎn)生漸變效果,并會(huì)表現(xiàn)出具有豐富層次的美感。本文主要講述兩種顏色RGB數(shù)值的梯級(jí)漸變算法。下面跟著小編一起來(lái)看下吧2017-03-03JS實(shí)現(xiàn)兼容各種瀏覽器的獲取選擇文本的方法【測(cè)試可用】
這篇文章主要介紹了JS實(shí)現(xiàn)兼容各種瀏覽器的獲取選擇文本的方法,可實(shí)現(xiàn)鼠標(biāo)拖動(dòng)選擇文本的同時(shí),下方顯示區(qū)同步實(shí)時(shí)顯示選中內(nèi)容的功能,涉及javascript響應(yīng)鼠標(biāo)事件及頁(yè)面元素動(dòng)態(tài)操作技巧,需要的朋友可以參考下2016-06-06js實(shí)現(xiàn)文章文字大小字號(hào)功能完整實(shí)例
這篇文章主要介紹了js實(shí)現(xiàn)文章文字大小字號(hào)功能的實(shí)現(xiàn)方法,可根據(jù)用戶習(xí)慣調(diào)整顯示文字的大小.詳細(xì)講述了實(shí)現(xiàn)這一功能的完整步驟.是非常實(shí)用的技巧,需要的朋友可以參考下2014-11-11JS中字符問(wèn)題(二進(jìn)制/十進(jìn)制/十六進(jìn)制及ASCII碼之間的轉(zhuǎn)換)
對(duì)于js的進(jìn)制轉(zhuǎn)換的一些方法分析2008-11-11js屬性對(duì)象的hasOwnProperty方法的使用
這篇文章主要介紹了js屬性對(duì)象的hasOwnProperty方法的使用,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2021-02-02