JS 設(shè)計(jì)模式之:工廠模式定義與實(shí)現(xiàn)方法淺析
本文實(shí)例講述了JS 設(shè)計(jì)模式之:工廠模式定義與實(shí)現(xiàn)方法。分享給大家供大家參考,具體如下:
前言
上次我們介紹了單例模式,沒看過的小伙伴可以看這個(gè)鏈接:
淺析 JS 設(shè)計(jì)模式之:單例模式
今天來說一說一種常見的設(shè)計(jì)模式:工廠模式。
工廠模式是一種創(chuàng)建對(duì)象的 創(chuàng)建型模式,遵循 DRY(Don't Repeat Yourself)原則。在該模式下,代碼將會(huì)根據(jù)具體的輸入或其他既定規(guī)則,自行決定創(chuàng)建哪種類型的對(duì)象。簡單點(diǎn)兒說就是,動(dòng)態(tài)返回需要的實(shí)例對(duì)象。
回顧上次的例子
讓我們繼續(xù)使用單例模式中的例子,一個(gè)日志工具 Logger :
class Logger {
log (...args) {
console.log(...args);
}
}
上面是最核心的 api,每次使用都需要使用 new Logger() 來創(chuàng)建一個(gè) logger 對(duì)象,然后使用方法就和 console 一樣啦~
多種 Logger
假如我們現(xiàn)在的代碼要支持 electron 環(huán)境,即日志既可以是 console 日志,也可以是 file 日志,那么我們就需要有兩種類型的 logger:
ConsoleLogger
// logger/console.js
class ConsoleLogger {
log (...args) {
console.log(...args)
}
}
export default ConsoleLogger
FileLogger
// logger/file.js
class FileLogger {
log (...args) {
dumpLog(...args)
}
}
export default FileLogger
這里先不用管 dumpLog 的具體實(shí)現(xiàn),只用知道它就是將日志寫在文件中的即可~
使用工廠
我們已經(jīng)有了兩種類型的 logger,但是這兩種 logger 的 api 實(shí)際上都是一樣的,在項(xiàng)目中直接導(dǎo)入當(dāng)然也可以使用,只不過每次都要導(dǎo)入對(duì)應(yīng)類型的模塊,然后再使用,像下面這樣:
使用 console logger
import ConsoleLogger from './logger/console' const logger = new ConsoleLogger()
使用 file logger
import FileLogger from './logger/file' const logger = new FileLogger()
是不是很繁瑣?如果還有其他 logger 類型,如遠(yuǎn)程日志,就會(huì)出現(xiàn)更多種使用方式了。為了把 logger 模塊的使用方式統(tǒng)一,這時(shí)候就會(huì)用到工廠模式啦~
讓我們新建一個(gè) index.js:
// logger/index.js
import ConsoleLogger from './console.js'
import FileLogger from './file.js'
function createLogger(type = 'console') {
if (type === 'console') {
return new ConsoleLogger()
} else if (type === 'file') {
return new FileLogger()
}
throw new Error(`Logger type not found: ${type}`)
}
export default createLogger
好了,這下我們的使用方式就會(huì)變成這樣:
import createLogger from './logger'
// console logger
const logger1 = createLogger('console')
// file logger
const logger2 = createLogger('file')
重構(gòu)一下
上面的 if else 不是很優(yōu)雅?如果有更多中 logger 類型添加起來很麻煩?那我們可以使用對(duì)象來映射一下,從而拋棄 if else,同時(shí)添加一個(gè) logger 選項(xiàng)。
// logger/index.js
import ConsoleLogger from './console.js'
import FileLogger from './file.js'
const loggerMap = {
console: ConsoleLogger,
file: FileLogger
}
// 可選參數(shù)一般放在最后面
function createLogger(options, type = 'console') {
const Logger = loggerMap[type]
if (Logger) {
return new Logger(options)
}
throw new Error(`Logger type not found: ${type}`)
}
上面這種封裝的方式,其實(shí)也符合SOLID原則中的開閉原則,即 對(duì)擴(kuò)展開放,對(duì)修改關(guān)閉,每當(dāng)我們添加一種logger類型時(shí),只需要新增一個(gè)文件,然后將構(gòu)造器注冊(cè)進(jìn)loggerMap中即可。而外面的使用方式都是不變的,這樣就用最少的修改完成了功能的新增,是不是很棒呀~
總結(jié)
下面我們來回顧一下工廠模式的優(yōu)點(diǎn):
- 動(dòng)態(tài)創(chuàng)建對(duì)象:可以用于需要在 運(yùn)行時(shí) 確定對(duì)象類型的情況。
- 抽象:封裝了對(duì)象創(chuàng)建的細(xì)節(jié),用戶不會(huì)接觸到對(duì)象的構(gòu)造器,只需要告訴工廠需要哪種對(duì)象。
- 可用性 / 可維護(hù)性:將相似的對(duì)象用一個(gè)工廠管理,提供統(tǒng)一的創(chuàng)建接口,滿足 開閉原則,使我們可以輕松添加多種類型的對(duì)象,而無需修改大量代碼。
好啦~!工廠模式就介紹到這里啦~ 下次我們講一講裝飾器模式~
參考內(nèi)容
- JavaScript Object Oriented Patterns: Factory Pattern
- 《JavaScript 設(shè)計(jì)模式》
- 《JavaScript 面向?qū)ο缶幊讨改稀?/li>
感興趣的朋友可以使用在線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對(duì)象屬性的檢測(cè)與獲取操作實(shí)例分析
這篇文章主要介紹了JS對(duì)象屬性的檢測(cè)與獲取操作,結(jié)合實(shí)例形式分析了JS針對(duì)ES5、ES6實(shí)現(xiàn)對(duì)象屬性的檢測(cè)與獲取常見操作技巧,需要的朋友可以參考下2020-03-03
Bootstrap Fileinput 4.4.7文件上傳實(shí)例詳解
這篇文章主要為大家詳細(xì)介紹了Bootstrap Fileinput 4.4.7文件上傳實(shí)例,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2018-07-07
微信小程序藍(lán)牙連接小票打印機(jī)實(shí)例代碼詳解
這篇文章主要介紹了微信小程序藍(lán)牙連接小票打印機(jī)實(shí)例代碼,代碼簡單易懂,非常不錯(cuò),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2019-06-06
layui radio點(diǎn)擊事件實(shí)現(xiàn)input顯示和隱藏的例子
今天小編就為大家分享一篇layui radio點(diǎn)擊事件實(shí)現(xiàn)input顯示和隱藏的例子,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧2019-09-09
layui左側(cè)菜單欄鼠標(biāo)懸停顯示菜單文字功能實(shí)現(xiàn)
layui封裝的左側(cè)菜單是固定寬度的,且左側(cè)菜單欄在css里改變寬度,效果并不是很好(還設(shè)計(jì)頭部菜單欄),如果寫js來讓菜單欄能夠拉伸,也比較麻煩,那怎么最簡單的,讓用戶看到菜單的文字呢,下面給大家分享layui左側(cè)菜單欄鼠標(biāo)懸停顯示菜單文字功能實(shí)現(xiàn),感興趣的朋友一起看看吧2024-06-06
Bootstrap實(shí)現(xiàn)各種進(jìn)度條樣式詳解
本篇文章主要介紹了Bootstrap實(shí)現(xiàn)各種進(jìn)度條樣式詳解 ,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-04-04
js/jQuery簡單實(shí)現(xiàn)選項(xiàng)卡功能
本篇文章主要是對(duì)js/jQuery簡單實(shí)現(xiàn)選項(xiàng)卡功能的示例代碼進(jìn)行了介紹,需要的朋友可以過來參考下,希望對(duì)大家有所幫助2014-01-01

