设计模式:装饰器

 

概念:装饰器作用是在在不会影响原有方法或类的功能的前提下,对它们进行增强。 属于AOP面向切面编程下的一种设计方案,更“优雅”地把“辅助功能逻辑”从“业务逻辑”中分离。( 比如将日志记录,性能统计,安全控制,异常处理等代码从业务逻辑代码中解耦出来出来)

本质:装饰器语法本质是  Object.defineProperty,装饰器是基于Object.definePropert的语法糖。

Object.defineProperty(obj, prop, descriptor)
  • 第一个参数是要装饰的对象target
  • 第二个参数是对象的属性名key
  • 第三个参数是该属性的描述对象descriptor
/**
 * {
 *   configurable: true,  // 可配置的
 *   enumerable: true,    // 可枚举的
 *   value: () => {},     // 该属性对应的值(数值,对象,函数,正则,日期等)
 *   writable: true,      // 可写入的
 * }
 */


var a = { b: () => {} }
var descriptor = Object.getOwnPropertyDescriptor(a, 'b')
console.log(descriptor)

 

五种装饰器

属性装饰器

type PropertyDecorator = (target: Object, propertyKey: string | symbol) => any;

let nameDecorator: PropertyDecorator = (target, propertyKey) => {

  const descriptor: PropertyDescriptor = {
    writable: true,
  };

  return descriptor
}

  

方法装饰器:(作用在类的方法上)

接受  target,name,descriptor 三个参数

interface PropertyDescriptor {
  configurable?: boolean;
  enumerable?: boolean;
  value?: any;
  writable?: boolean;
  get?(): any;
  set?(v: any): void;
}


// tyoe 实现
type MethodDecorator = (target: Object,name: PropertyKey,descriptor: PropertyDescriptor) =>PropertyDescriptor;


//interface 实现

interface  MethodDecorator2{
  (target: Object,name: string|symbol,descriptor: PropertyDescriptor):PropertyDescriptor
}

 实现日志模块 

let log = (type:string):MethodDecorator2 => {

  return (target, name, descriptor)  => {
    const method = descriptor.value;
    descriptor.value =  (...args) => {
      console.info(`(${type}) 正在执行: ${name}(${args}) = ?`);
      let ret;
      try {
        ret = method.apply(target, args);
        console.info(`(${type}) 成功 : ${name}(${args}) => ${ret}`);
      } catch (error) {
        console.info(`(${type}) 失败: ${name}(${args}) => ${error}`);
      }
      return ret;
    }
    return descriptor
  }
}



class IronMan {
  @log('IronMan 自检阶段')
  check(){
    return '检查完毕';
  }
  @log('IronMan 攻击阶段')
  attack(){
    return '击倒敌人';
  }
  @log('IronMan 机体报错')
  error(){
    throw 'Something is wrong!';
  }
}

var tony = new IronMan();
tony.check();
tony.attack();

  

 类装饰器:(作用在类上 decorator)

hoc

function hocComponent(namespace) {
  return WrappedComponent => {
    return class extends React.Component {
      constructor(props) {
        super(props);
     
      }

      render() {
        const pp= Object.assign({}, this.props, {
          name: namespace
        });

        
        return <div>
          <WrappedComponent {...pp} />
          <div>{namespace}</div>
        </div>;
      }

      componentWillUnmount() {
       
      }
    };
  };
}

// 装饰组件
@hocComponent('eventSpace')
class Dashboard  extends React.Component {
  constructor(props) {
    super(props);
 
  }
  render() {
 
    return <div>222{this.props.name}3</div>;
  }
}
export default Dashboard;

  

  

作用在类上的 decorator, 接受一个target 参数是类本身,从而对类添加静态属性

// 这里的 `target` 是类本身
function doge (target) {
  target.isDoge = true
}

@doge
class Dog {}

console.log(Dog.isDoge)
// true

  

 

  

 

posted @ 2021-08-31 11:19  break_happy  Views(78)  Comments(0Edit  收藏  举报