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

相关文章
相关标签/搜索