• 装饰器模式


    介绍

    • 为对象添加新功能
    • 不改变其原有的结构和功能

    UML类图

    传统UML类图
    简化后的UML类图

    代码演示

    class Circle {
        draw() {
            console.log('画一个圆形')
        }
    }
    
    class Decorator {
        constructor(circle) {
            this.circle = circle
        }
        draw() {
            this.circle.draw()
            this.setRedBorder(circle)
        }
        setRedBorder(circle) {
            console.log('设置红色边框');
        }
    }
    
    // 测试代码
    let circle = new Circle();
    circle.draw();
    let decorator = new Decorator(circle);
    decorator.draw();
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24

    场景

    ES7装饰器

    • 装饰类
      简单demo:
    // 简单demo
    @testDec 
    class Demo {
        
    }
    
    function testDec(target) {
        target.isDec = true
    }
    alert(Demo.isDec)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    可以传参数:

    // 可以加参数
    function testDec(isDec) {
        return function(target) {
            target.isDec = isDec;
        }
    }
    
    @testDec(true)
    class Demo {
        // ...
    }
    alert(Demo.isDec) // true
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    mixin示例:

    function mixins(...list) {
        return function (target) {
            Object.assign(target.prototype, ...list)
        }
    }
    
    const Foo = {
        foo() {
            alert('foo')
        }
    }
    
    @mixins(Foo)
    class MyClass{}
    
    let obj = new MyClass();
    obj.foo() // 'foo'
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 装饰方法

    例1:

    class Person {
        constructor() {
            this.first = 'A'
            this.last = 'B'
        }
        
        // 装饰方法
        @readonly 
        name() {
            return `${this.first} ${this.last}`
        }
    }
    
    var p = new Person()
    console.log(p.name())
    // p.name = function() {} // 这里会报错,因为name是只读属性
    
    function readonly(target, name, descriptor) {
        // descriptor属性描述对象(Object.defineProperty中会用到),原来的值如下
        //{
        //  value: specifiedFunction,
        //  enumerable: false,
        //  configurable: true,
        //  writable: true
        //};
        descriptor.writable = false;
        return descriptor;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28

    例2:

    class Math {
        // 装饰方法
        @log
        add(a, b) {
            return a + b;
        }
    }
    
    const math = new Math();
    const result = math.add(2, 4); // 执行add时,会自动打印日志,因为有@log装饰器
    console.log('result', result);
    
    function log(target, name, descriptor) {
        var oldValue = descriptor.value;
        
        descriptor.value = function() {
            console.log(`Calling ${name} with`, arguments);
            return oldValue.apply(this, arguments);
        };
        
        return descriptor;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22

    core-decorators

    // 首先安装 npm i core-decotators --save
    
    // 开始编码:
    import { readonly } from 'core-decorators'
    
    class Person {
        @readonly
        name() {
            return 'zhang'
        }
    }
    
    let p = new Person()
    alert(p.name())
    // p.name = function() {} // 此处会报错
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    import { deprecate } from 'core-decorators';
    
    class Person {
        @deprecate 
        facepalm() {}
        
        @deprecate('We stopped facepalming')
        facepalmHard() {}
        
        @deprecate('We stopped facepalming', {
            url: 'http://knowyourmeme.com/memes/facepalm'
        })
        facepalmHarder() {}
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    设计原则验证

    • 将现有对象和装饰器进行分离,两者独立存在
    • 符合开放封闭原则
  • 相关阅读:
    Docker入门到精通教程
    接口压力测试 jmeter--进阶篇(三)
    IT业务运维可观测技术的发展浅析
    Spring bean
    深入浅出MySQL事务和锁定语句
    【数据结构】八大经典排序(两万字大总结)
    使用Spring Boot进行分页
    【GO】LGTM_Grafana_gozero_配置trace(4)_代码实操及追踪
    计算机死机的时候,它在干什么?
    SpringBoot与Loki的那些事
  • 原文地址:https://blog.csdn.net/linanran1027/article/details/132839792