装饰器模式

介绍

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

UML类图

装饰器模式_第1张图片
装饰器模式_第2张图片

代码演示

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();

场景

ES7装饰器

  • 装饰类
    简单demo:
// 简单demo
@testDec 
class Demo {
    
}

function testDec(target) {
    target.isDec = true
}
alert(Demo.isDec)

可以传参数:

// 可以加参数
function testDec(isDec) {
    return function(target) {
        target.isDec = isDec;
    }
}

@testDec(true)
class Demo {
    // ...
}
alert(Demo.isDec) // true

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:

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;
}

例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;
}

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() {} // 此处会报错
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() {}
}

设计原则验证

  • 将现有对象和装饰器进行分离,两者独立存在
  • 符合开放封闭原则

你可能感兴趣的:(装饰器模式,javascript,开发语言)