对于装饰器模式的理解,可以举例。在手机上可以套上一个手机壳,不会影响手机的正常使用功能,可以给手机起到装饰的作用,并且保护手机不受到伤害。
对于装饰器模式的应用场景,比如 ES7 装饰器,core-decorators 等等。
装饰器模式的设计原则验证,将现有对象和装饰器进行分离,两者独立存在,符合开放封闭原则。

介绍

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

    装饰器原理

    ```javascript @decorator class Demo { // … }

// 等同于 class Demo {} Demo = decorator(Demo) || Demo;

  1. <a name="4LfMV"></a>
  2. # 常见使用场景
  3. - 装饰类
  4. ```javascript
  5. @testDec
  6. class Demo {
  7. // ...
  8. }
  9. function testDec(target) {
  10. target.isDec = true;
  11. }
  12. alert(Demo.isDec);
  • 装饰类-参数 ```javascript @testDec(true) class Demo { // … }

function testDec(isDec) { return (target) => { target.isDec = isDec; }; }

alert(Demo.isDec);

  1. - 装饰类-mixin
  2. ```javascript
  3. function mixins(...list) {
  4. return (target) => {
  5. Object.assign(target.prototype, ...list);
  6. };
  7. }
  8. const Foo = {
  9. foo() {
  10. alert("foo");
  11. },
  12. };
  13. @mixins(Foo)
  14. class MyClass {}
  15. let obj = new MyClass();
  16. obj.foo();
  • 装饰方法-1 ```javascript /*
    • @param {*} target
    • @param {*} name
    • @param {*} desciptor 属性描述对象,Object.defineProperty 用到,原来值(value: specifiedFunction, enumerable: false, configurable: true, writable: true)
    • @returns */ function readonly(target, name, desciptor) { desciptor.writable = false; return desciptor; }

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

  1. @readonly
  2. name() {
  3. return `${this.first}-${this.last}`;
  4. }

}

let p = new Person(); console.log(p.name());

// 这里会报错,因为 name 是只读属性 // p.name = () => { // alert(“dd”); // };

  1. - 装饰方法-2
  2. ```javascript
  3. /**
  4. *
  5. * @param {*} target
  6. * @param {*} name
  7. * @param {*} desciptor 属性描述对象,Object.defineProperty 用到,原来值(value: specifiedFunction, enumerable: false, configurable: true, writable: true)
  8. * @returns
  9. */
  10. function log(target, name, desciptor) {
  11. let oldValue = desciptor.value;
  12. desciptor.value = () => {
  13. console.log(`calling ${name} width`, arguments);
  14. return oldValue.apply(this, arguments);
  15. };
  16. return desciptor;
  17. }
  18. class Math {
  19. @log
  20. add(a, b) {
  21. return a + b;
  22. }
  23. }
  24. let math = new Math();
  25. const result = math.add(2, 4);
  26. console.log("result", result);
  • core-decorators ```javascript import { deprecate } from “core-decorators”;

class Person { @deprecate facepalm() {}

  1. @deprecate("We stopped facepalming")
  2. facepalmHard() {}
  3. @deprecate("We stopped facepalming", {
  4. url: "http://knowyourmeme.com/memes/facepalm",
  5. })
  6. facepalmHarder() {}

}

let person = new Person(); person.facepalm(); person.facepalmHard(); person.facepalmHarder();

  1. <a name="i9iMF"></a>
  2. # 装饰器模式代码示例
  3. ```javascript
  4. class Circle {
  5. draw() {
  6. console.log("画一个圆形");
  7. }
  8. }
  9. class Decorator {
  10. constructor(circle) {
  11. this.circle = circle;
  12. }
  13. draw() {
  14. this.circle.draw();
  15. this.setRedBorder(this.circle);
  16. }
  17. setRedBorder(circle) {
  18. console.log("设置红色边框");
  19. }
  20. }
  21. // 测试代码
  22. let circle = new Circle();
  23. circle.draw();
  24. let dec = new Decorator(circle);
  25. dec.draw();

设计原理验证

  • 将旧接口和使用者进行分离
  • 符合开放封闭原则