Javascript design pattern system explanation and application——study notes 5-decorator pattern

Decorator mode

  • Add new features to objects
  • Does not change its original structure and function

Insert picture description here

class Circle {
    
    
  draw() {
    
    
    console.log('画一个圆形')
  }
}

class Decorator {
    
    
  constructor(circle) {
    
    
    this.circle = circle
  }
  draw() {
    
    
    this.circle.draw()
    this.setRedBord(circle)
  }
  setRedBord(circle) {
    
    
    console.log('设置红色边框')
  }
}

// 测试
let circle = new Circle()
circle.draw()
let dec = new Decorator(circle)
dec.draw()

Scenes

  • ES7 decorator
  • core-decorators
ES7 decorator

Decoration


@testDec
class Demo {
    
    
  // ...
}

function testDec(target) {
    
    
  target.isDec = true;
}

alert(Demo.isDec) // true

Parameter form:

function testDec(isDec) {
    
    
  return funciton (target) {
    
    
    target.isDec = isDec
  }
}
@testDec(false)
class Demo {
    
    

}
alert(Demo.isDec)  // false

Decorator-mixin example

function mixin(...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'

Decoration method

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 = function () {
    
    }  // 报错,因为name是只读属性

@readonlyRealization of

function readonly(target, name, descriptor) {
    
    
  // descriptor 属性描述对象, Object.defineProperty中会用到, 原来的值如下;
  // {
    
    
  //   value: specifiedFunction,
  //   enumerable: false,   // 可枚举
  //   configurable: true,  // 可配置
  //   writable: true       // 可写
  // }
  descriptor.writable = false  // 变为不可写
  return descriptor
}

Decoration method

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)

@log decorator method implementation

function log(target, name, descriptor) {
    
    
  let oldValue = descriptor.value;  // zhuan shi
  descriptor.value = function() {
    
    
    console.log(`Calling ${
      
      name} with`, arguments)
    reutrn oldValue.apply(this, arguments)
  };
  return descriptor;
}

js decorator third-party lib library
core-decorators

import {
    
     deprecate } from 'core-decorators'   // 提示废弃

Design principle verification

  • Separate the existing object and the decorator, the two exist independently
  • Comply with the open and closed principle

Guess you like

Origin blog.csdn.net/weixin_40693643/article/details/108820248