什么是裝飾者模式?
定義:動態地給一個對象添加一些額外的職責。就增加功能來說,裝飾器模式相比生成子類更為靈活。
主要解決:一般的,我們為了擴展一個類經常使用繼承方式實現,由於繼承為類引入靜態特征,並且隨着擴展功能的增多,子類會很膨脹。
何時使用:在不想增加很多子類的情況下擴展類。
如何解決:將具體功能職責划分,同時繼承裝飾者模式。
應用實例: 1、孫悟空有 72 變,當他變成"廟宇"后,他的根本還是一只猴子,但是他又有了廟宇的功能。 2、不論一幅畫有沒有畫框都可以掛在牆上,但是通常都是有畫框的,並且實際上是畫框被掛在牆上。在掛在牆上之前,畫可以被蒙上玻璃,裝到框子里;這時畫、玻璃和畫框形成了一個物體。
優點:裝飾類和被裝飾類可以獨立發展,不會相互耦合,裝飾模式是繼承的一個替代模式,裝飾模式可以動態擴展一個實現類的功能。
缺點:多層裝飾比較復雜。
使用場景: 1、擴展一個類的功能。 2、動態增加功能,動態撤銷。
注意事項:可代替繼承。
JavaScript中的裝飾者模式
生活中的例子:天氣冷了,就添加衣服來保暖;天氣熱了,就將外套脫下;這個例子很形象地含蓋了裝飾器的神韻,隨着天氣的冷暖變化,衣服可以動態的穿上脫下。
let wear = function() { console.log('穿上第一件衣服') } const _wear1 = wear wear = function() { _wear1() console.log('穿上第二件衣服') } const _wear2 = wear wear = function() { _wear2() console.log('穿上第三件衣服') } wear() // 穿上第一件衣服 // 穿上第二件衣服 // 穿上第三件衣服
這種方式有以下缺點:1:臨時變量會變得越來越多;2:this 指向有時會出錯
AOP 裝飾函數
// 前置代碼 Function.prototype.before = function(fn) { const self = this return function() { fn.apply(this, arguments) return self.apply(this, arguments) } } // 后置代碼 Function.prototype.after = function(fn) { const self = this return function() { self.apply(this, arguments) return fn.apply(this, arguments) } }
用后置代碼來實驗下上面穿衣服的 demo,
const wear1 = function() { console.log('穿上第一件衣服') } const wear2 = function() { console.log('穿上第二件衣服') } const wear3 = function() { console.log('穿上第三件衣服') } const wear = wear1.after(wear2).after(wear3) wear() // 穿上第一件衣服 // 穿上第二件衣服 // 穿上第三件衣服
但這樣子有時會污染原生函數,可以做點通變
const after = function(fn, afterFn) { return function() { fn.apply(this, arguments) afterFn.apply(this, arguments) } } const wear = after(after(wear1, wear2), wear3) wear()