zhangdizhangdi

命令模式 📖

定义

命令模式(Command Pattern),请求以命令的形式包裹在对象中,并传给调用对象。调用对象寻找可以处理该命令的合适的对象,并把该命令传给相应的对象,该对象执行命令。

向某些对象发送请求,但是并不知道请求的接收者是谁,也不知道被请求的操作是什么。

实现

js
function add(x, y) {
  return x + y
}
function sub(x, y) {
  return x - y
}
function mul(x, y) {
  return x * y
}
function div(x, y) {
  return x / y
}

class Command {
  constructor(execute, undo, value) {
    this.execute = execute
    this.undo = undo
    this.value = value
  }
}

const AddCommand = function (value) {
  return new Command(add, sub, value)
}

const SubCommand = function (value) {
  return new Command(sub, add, value)
}

const MulCommand = function (value) {
  return new Command(mul, div, value)
}

const DivCommand = function (value) {
  return new Command(div, mul, value)
}

class Calculator {
  current = 0
  commands = []

  action(command) {
    let name = command.execute.toString().substr(9, 3)
    return name.charAt(0).toUpperCase() + name.slice(1)
  }

  execute(command) {
    this.current = command.execute(this.current, command.value)
    this.commands.push(command)
    console.log(
      `${this.action(command)}: ${command.value},current: ${this.current}`,
    )
  }

  undo() {
    let command = this.commands.pop()
    this.current = command.undo(this.current, command.value)
    console.log(
      `Undo ${this.action(command)}: ${command.value},current: ${this.current}`,
    )
  }

  getCurrentValue() {
    return this.current
  }
}

const calculator = new Calculator()

calculator.execute(new AddCommand(100))
calculator.execute(new SubCommand(24))
calculator.execute(new MulCommand(6))
calculator.execute(new DivCommand(2))

calculator.undo()
calculator.undo()

console.log('Value: ' + calculator.getCurrentValue())
执行结果
Add: 100,current: 100
Sub: 24,current: 76
Mul: 6,current: 456
Div: 2,current: 228
Undo Div: 2,current: 456
Undo Mul: 6,current: 76
Value: 76

参考