装饰模式 - Decorator

119 阅读1分钟

一、定义

以动态地给某个对象添加一些额外的职责,而不会影响从这个类中派生的其他对象。
装饰器模式就是使用在对已有的目标功能存在不足,需要增强时,动态地给一个对象增加一些额外的职责,增加对象功能来说,装饰模式比生成子类实现更为灵活。

二、核心

是为对象动态加入行为,经过多重包装,可以形成一条装饰链

三、实现

// 程序员
class Coder {
  skill () {
    console.log('--->我是一个程序猿,我:')
    console.log('会编程')
  }
}

// 装饰器,会翻墙
class VPNDecortor {
  constructor(coder) {
    this.coder = coder
  }

  skill () {
    this.coder.skill()
    console.log('会翻墙')
  }
}
// 装饰器,会做饭
class CookDecortor {
  constructor(coder) {
    this.coder = coder
  }

  skill () {
    this.coder.skill()
    console.log('会做饭')
  }
}

// 测试 
const coder = new Coder()
const coder2 = new VPNDecortor(coder)
const coder3 = new CookDecortor(coder2)
coder.skill()
coder2.skill()
coder3.skill()

// 输出:
--->我是一个程序猿,我:
会编程
--->我是一个程序猿,我:
会编程
会翻墙
--->我是一个程序猿,我:
会编程
会翻墙
会做饭

在JS中,我们也可以使用更通用的装饰函数

// ========= 装饰函数 =========
function decoratorAfter (fn, afterFn) {
  return function () {
    const ret = fn.apply(this, arguments)
    afterFn.apply(this. arguments)
  }
}

function open () {
  console.log('打开冰箱')
}
function push () {
  console.log('把大象推进去')
}
function close () {
  console.log('关上冰箱')
}

let action = decoratorAfter(open, push)
action = decoratorAfter(action, close)
action() 

// 输出:
打开冰箱
把大象推进去
关上冰箱

跳转:设计模式目录