美文网首页
装饰器模式

装饰器模式

作者: hankchang | 来源:发表于2018-08-18 14:49 被阅读0次

装饰器模式

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

示例

zs1.png zsuml.png
class Circle {
  draw() {
    console.log("画一个圆形");
  }
}
class Decorator {
  constructor(circle) {
    this.circle = circle;
  }
  draw() {
    this.circle.draw();
    this.setRedBorder(circle);
  }
  setRedBorder(circle) {
    console.log("设置红色边框");
  }
}

const circle = new Circle();
circle.draw();

const dec = new Decorator(circle);
dec.draw();

场景

ES7 装饰器

安装 babel 插件

  • npm i -D babel-plugin-transform-decorators-legacy

配置.babelrc

  • 验证配置
@testDec
class Demo {}
function testDec(target) {
  target.isDec = true;
}
console.log(Demo.isDec);
  • mixin
function mixin(...list) {
  return function(target) {
    Object.assign(target.prototype, ...list);
  };
}

const Foo = {
  foo() {
    console.log("foo");
  }
};

@mixin(Foo)
class MyClass {}

const obj = new MyClass();
obj.foo();
  • 装饰方法
function readonly(target, name, descriptor) {
  descriptor.writable = false;
  return descriptor;
}

class Person {
  constructor() {
    this.first = "A";
    this.last = "B";
  }

  @readonly
  name() {
    return `${this.first} ${this.last}`;
  }
}

// 测试
const p = new Person();
console.log(p.name());

p.name = 1; // 报错, name是只读的
function log(target, name, descriptor) {
  const oldValue = descriptor.value;
  descriptor.value = function() {
    console.log(`calling ${name} with`, arguments);
    return oldValue.apply(this, arguments);
  };
  return descriptor;
}

class Math {
  @log
  add(a, b) {
    return a + b;
  }
}

// 测试
const math = new Math();
console.log(math.add(2, 4));

core-decorators

  • 第三方开源 lib
  • 提供常用的装饰器
  • 查阅 GitHub文档
cd1.png cd2.png cd3.png

设计原则验证

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

相关文章

网友评论

      本文标题:装饰器模式

      本文链接:https://www.haomeiwen.com/subject/caqfiftx.html