JavaScript?裝飾器模式用法詳解
什么是裝飾器模式
裝飾器模式(Decorator Pattern)是一種結(jié)構(gòu)型設(shè)計(jì)模式,它允許動(dòng)態(tài)地向一個(gè)對(duì)象添加新的行為。在不改變對(duì)象本身的情況下,通過將對(duì)象包裝在一個(gè)裝飾器中,來增強(qiáng)對(duì)象的功能。這個(gè)模式的核心是使用一個(gè)裝飾器類,來包裝一個(gè)被裝飾的類,使得裝飾器類可以動(dòng)態(tài)地添加新的功能或者修改已有的功能。
裝飾器模式的主要用途是為一個(gè)原始對(duì)象添加新的功能或者修改已有的功能,同時(shí)保持原始對(duì)象的接口不變,并且可以在運(yùn)行時(shí)動(dòng)態(tài)地添加或刪除功能。
為什么要有裝飾器模式
在開發(fā)過程中,我們經(jīng)常需要擴(kuò)展一個(gè)類或?qū)ο蟮墓δ?,但是直接修改類或?qū)ο罂赡軙?huì)導(dǎo)致代碼復(fù)雜性和可維護(hù)性下降。裝飾器模式提供了一種優(yōu)雅的方式來擴(kuò)展類或?qū)ο蟮墓δ?,且無需修改基本的對(duì)象或類。它使代碼更加模塊化、易于維護(hù)和擴(kuò)展。
裝飾器模式應(yīng)用場(chǎng)景
JS裝飾器模式通常用于以下場(chǎng)景:
- 將對(duì)象的功能添加到已存在的對(duì)象中,而不影響原始對(duì)象的接口。
- 實(shí)現(xiàn)AOP(面向切面編程)并在多個(gè)組件之間共享代碼。
- 通過運(yùn)行時(shí)組合來實(shí)現(xiàn)功能,而不是繼承。
舉個(gè)栗子
下面我們來舉 2 個(gè)例子,更加具象的理解什么是裝飾器模式:
給汽車加個(gè)真皮座椅
class Car { constructor() { this.price = 10000; this.speed = '100 km/h'; } getPrice() { return this.price; } getSpeed() { return this.speed; } } // 汽車裝飾器 class CarDecorator { constructor(car) { this.car = car; } getPrice() { return this.car.getPrice(); } getSpeed() { return this.car.getSpeed(); } } // 真皮座椅裝飾器 class LeatherSeatsDecorator extends CarDecorator { constructor(car) { super(car); this.price = 1000; this.description = 'Leather seats'; } getPrice() { return this.car.getPrice() + this.price; } getDescription() { return this.car.getDescription() + ', ' + this.description; } } let car = new Car(); console.log(car.getPrice()); // 10000 // 帶有真皮座椅的汽車 let carWithLeatherSeats = new LeatherSeatsDecorator(car); console.log(carWithLeatherSeats.getPrice()); // 11000 console.log(carWithLeatherSeats.getDescription()); // undefined, Leather seats
在上面的代碼中,我們定義了一個(gè) Car 類作為原始對(duì)象,并且定義了一個(gè) CarDecorator 類作為裝飾器類。然后我們定義了一個(gè) LeatherSeatsDecorator 類,它繼承自 CarDecorator 類,用來添加真皮座椅的功能。
一個(gè)簡(jiǎn)單的數(shù)據(jù)緩存
class DataService { fetchData() { console.log("Fetching data from server..."); return [1, 2, 3]; } } class DataCacheDecorator { constructor(dataService) { this.dataService = dataService; this.cache = null; } fetchData() { if (this.cache === null) { console.log("Cache not exist..."); this.cache = this.dataService.fetchData(); } else { console.log("Data retrieved from cache"); } return this.cache; } } let dataService = new DataService(); dataService = new DataCacheDecorator(dataService); console.log(dataService.fetchData()); console.log(dataService.fetchData());
上述代碼將有如下輸出:
Cache not exist...
Fetching data from server...
[1, 2, 3]
Data retrieved from cache
[1, 2, 3]
總結(jié)
JS裝飾器模式提供了一種優(yōu)雅的方式來擴(kuò)展類或?qū)ο蟮墓δ?,而無需修改基本的對(duì)象或類。它使代碼更加模塊化、易于維護(hù)和擴(kuò)展。在適當(dāng)?shù)那闆r下,使用裝飾器模式可以提高代碼的可讀性和可維護(hù)性。
為了更好的理解裝飾器模式,本文選取了 2 個(gè)簡(jiǎn)單易理解的例子。真實(shí)場(chǎng)景下 JS 裝飾器模式的應(yīng)用要復(fù)雜的多,目前 ES6、TypeScript、React、Express、Koa、Mobx、Redux 等場(chǎng)景都已經(jīng)廣泛使用了 JS 裝飾器,以后文章會(huì)針對(duì)上述場(chǎng)景進(jìn)行具體詳細(xì)介紹。
到此這篇關(guān)于JavaScript 裝飾器模式詳解的文章就介紹到這了,更多相關(guān)JavaScript 裝飾器模式內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
js常用方法、檢查是否有特殊字符串、倒序截取字符串操作完整示例
這篇文章主要介紹了js常用方法、檢查是否有特殊字符串、倒序截取字符串操作,結(jié)合完整實(shí)例形式分析了JavaScript字符串轉(zhuǎn)換、檢測(cè)、倒序、截取等相關(guān)操作技巧,需要的朋友可以參考下2020-01-01200行代碼實(shí)現(xiàn)blockchain 區(qū)塊鏈實(shí)例詳解
這篇文章主要介紹了200行代碼實(shí)現(xiàn)blockchain 區(qū)塊鏈的相關(guān)知識(shí),非常不錯(cuò),具有參考借鑒價(jià)值,需要的朋友參考下吧2018-03-03微信小程序?qū)崿F(xiàn)錄音時(shí)的麥克風(fēng)動(dòng)畫效果實(shí)例
這篇文章主要給大家介紹了關(guān)于微信小程序?qū)崿F(xiàn)錄音時(shí)的麥克風(fēng)動(dòng)畫效果的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家學(xué)習(xí)或者使用微信小程序具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面來一起學(xué)習(xí)學(xué)習(xí)吧2019-05-05touch.js 拖動(dòng)、縮放、旋轉(zhuǎn) (鼠標(biāo)手勢(shì))功能代碼
這篇文章主要介紹了touch.js 拖動(dòng)、縮放、旋轉(zhuǎn) (鼠標(biāo)手勢(shì))功能,代碼簡(jiǎn)單易懂,非常不錯(cuò),具有參考借鑒價(jià)值,需要的朋友可以參考下2017-02-02基于BootStrap multiselect.js實(shí)現(xiàn)的下拉框聯(lián)動(dòng)效果
當(dāng)option特別多時(shí),一般的下拉框選擇起來就有點(diǎn)力不從心了,所以使用multiselect是個(gè)很好的選擇。在網(wǎng)上找了半天找到了解決方案,具體實(shí)現(xiàn)代碼大家參考下本文吧2017-07-07JS驗(yàn)證 只能輸入小數(shù)點(diǎn),數(shù)字,負(fù)數(shù)的實(shí)現(xiàn)方法
下面小編就為大家?guī)硪黄狫S驗(yàn)證 只能輸入小數(shù)點(diǎn),數(shù)字,負(fù)數(shù)的實(shí)現(xiàn)方法。小編覺得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2016-10-10JS實(shí)現(xiàn)密碼框的顯示密碼和隱藏密碼功能示例
這篇文章主要介紹了JS實(shí)現(xiàn)密碼框的顯示密碼和隱藏密碼功能,涉及javascript針對(duì)頁(yè)面form表單元素動(dòng)態(tài)操作的相關(guān)技巧,需要的朋友可以參考下2016-12-12淺談javascript中call()、apply()、bind()的用法
一直對(duì)Javascript中的apply/call/bind的用法很模糊,恰好看到了這篇文章。對(duì)三者之間的區(qū)別與聯(lián)系算是有了比較清晰的認(rèn)識(shí)。這里記錄下來,分享給大家。2015-04-04js下關(guān)于onmouseout、事件冒泡的問題經(jīng)驗(yàn)小結(jié)
第3次遇到這個(gè)問題,于是總結(jié)了一下,將此短文發(fā)在首頁(yè),希望對(duì)瀏覽器事件機(jī)制有所了解的大俠們給予解答2010-12-12