JS設計模式初識(十二)-裝飾器模式

定義

在《設計模式》成書以前,GoF 原想把裝 飾者(decorator)模式稱爲包裝器(wrapper) 模式。從功能上而言,decorator能很好地描述這個模式,但從結構上看,wrapper的說法更加 貼切。裝飾者模式將一個對象嵌入另外一個對象之中,實際上至關於這個對象被另外一個對象包 裝起來,造成一條包裝鏈。請求隨着這條鏈依次傳遞到全部的對象,每一個對象都有處理這條 請求的機會。 使用場景像數據上報, 日誌記錄等。設計模式

12.1 引入裝飾器

保證原來代碼不變的同時增長新功能bash

function log1() {
        console.log(1);
    }
    const _log1 = log1;
    log1 = function() {
        _log1();
        console.log(2); // 新增的功能
    }
複製代碼

新增功能 卻不要改變log1 的源代碼, 保存源代碼的引用, 使用裝飾的模式新增功能app

12.2 使用AOP實現裝飾器模式

Function.prototype.before = function(beforeFn) {
        const self = this; // 保存原函數的引用
        return function(...args) {
            beforeFn.apply(this, args);
            return self.apply(this, args);
        }
    }
    
    Function.prototype.after = function (afterFn) {
        const self = this;
        return function(...args) {
            const ret = self.apply(this, args);
            afterFn.apply(this, args);
            return ret;
        }
    }
    
    window.onload = () => {
        console.log('onload', 1);
    }
    
    window.onload = (window.onload || (() => {})).after(() => { console.log(2) }).after(() => { console.log(3) }).before(() => { console.log('before')});
    // => before, onload 1, 2, 3
複製代碼

這裏有個問題, before 和after 執行的時候是 return 一個函數, 那這個函數是何時執行的呢, 誰調用了呢。這個沒想明白函數

12.3 總結

裝飾者模式和代理模式的結構看起來很是相像,這兩種模式都描述了怎樣爲對象提供 必定程度上的間接引用,它們的實現部分都保留了對另一個對象的引用,而且向那個對象發送請求。 代理模式和裝飾者模式最重要的區別在於它們的意圖和設計目的。代理模式的目的是,當直 接訪問本體不方便或者不符合須要時,爲這個本體提供一個替代者。本體定義了關鍵功能,而代 理提供或拒絕對它的訪問,或者在訪問本體以前作一些額外的事情。裝飾者模式的做用就是爲對象動態加入行爲。換句話說,代理模式強調一種關係(Proxy與它的實體之間的關係),這種關係能夠靜態的表達,也就是說,這種關係在一開始就能夠被肯定。而裝飾者模式用於一開始不能肯定對象的所有功能時。代理模式一般只有一層代理本體的引用,而裝飾者模式常常會造成一條 長長的裝飾鏈。ui

相關文章
相關標籤/搜索