命令模式主要应用在需要延迟执行请求、支持撤回的场景中,可能在文本编辑器中有应用,我目前没有使用过,这里就留坑了。
命令模式本质上就是将数据和操作封装为一个对象,实现操作的撤回、延迟等。
这里贴一下 Youtube
一个博主举的 计算器例子 (opens new window)。
首先是一个支持加减乘除的计算器:
class Calculator {
constructor(){
this.value = 0
}
add(valueToAdd){
this.value = this.value + valueToAdd
}
subtract(valueToSubtract){
this.value = this.value - valueToSubtract
}
multiply(valueToMultiply){
this.value = this.value * valueToMultiply
}
divide(valueToDivide){
this.value = this.value / valueToDivide
}
}
const calculator = new Calculator()
calculator.add(10)
console.log(calculator.value) // 10
calculator.divide(2)
console.log(calculator.value) // 5
如果需要给计算器增加撤回的功能,就可以使用命令模式了。
我们把每一步操作都封装为一个类作为命令对象,类中包含了操作数和操作方法,然后用一个数组记录所有的命令对象。
class Calculator {
constructor(){
this.value = 0
this.history = []
}
executeCommand(command){
this.value = command.execute(this.value)
this.history.push(command)
}
undo(){
const command = this.history.pop()
this.value = command.undo(this.value)
}
add(valueToAdd){
this.value = this.value + valueToAdd
}
subtract(valueToSubtract){
this.value = this.value - valueToSubtract
}
multiply(valueToMultiply){
this.value = this.value * valueToMultiply
}
divide(valueToDivide){
this.value = this.value / valueToDivide
}
}
class AddCommand {
constructor(valueToAdd){
this.valueToAdd = valueToAdd
}
execute(currentValue){
return currentValue + this.valueToAdd
}
undo(currentValue){
return currentValue - this.valueToAdd
}
}
class SubtractCommand {
constructor(valueToSubtract){
this.valueToSubtract = valueToSubtract
}
execute(currentValue){
return currentValue - this.valueToSubtract
}
undo(currentValue){
return currentValue + this.valueToSubtract
}
}
class MultiplyCommand {
constructor(valueToMultiply){
this.valueToMultiply = valueToMultiply
}
execute(currentValue){
return currentValue * this.valueToMultiply
}
undo(currentValue){
return currentValue / this.valueToMultiply
}
}
class DivideCommand {
constructor(valueToDivide){
this.valueToDivide = valueToDivide
}
execute(currentValue){
return currentValue / this.valueToDivide
}
undo(currentValue){
return currentValue * this.valueToDivide
}
}
const calculator = new Calculator()
calculator.executeCommand(new AddCommand(10))
calculator.executeCommand(new MultiplyCommand(2))
console.log(calculator.value) // 20
calculator.undo()
console.log(calculator.value) // 10
# 总
命令模式的思想比较有意思,将数据和操作封装,实现上在 js
中很简单,我们甚至也不需要 class
,直接通过字面量对象传递也可以。
但实际开发中目前还没用到过,此处留坑。
Last Updated: 3/5/2022, 1:53:59 AM