什么是命令模式?
命令模式(Command Pattern)是一种数据驱动的设计模式,它属于行为型模式。请求以命令的形式包裹在对象中,并传给调用对象。调用对象寻找可以处理该命令的合适的对象,并把该命令传给相应的对象,该对象执行命令。
实例应用
我们要做一个简单的编辑器,先来看看没有使用命令模式的代码。(忽略定义方法意义所在)
class Editor {
constructor() {
this.content= ''
}
write(content) {
this.content+=content
return this
}
read() {
console.log(this.content)
return this
}
space() {
this.content+= ' '
return this
}
}
const editor = new Editor()
editor.write('hello').space().write('zkk!').read() // => 'hello zkk!'
以上代码加以扩展,如果是普通的编辑需求,确实够用了。
如果我们要加入撤回和多人编辑的功能,那么我们就需要维护一个操作记录的队列。
在每个方法中添加记录操作的相关代码,显然很费力,后期维护成本也很大,我们看看如何通过命令模式来改造。
class Editor {
constructor() {
this.content= ''
this.operator = []
}
write(content) {
this.content+=content
}
read() {
console.log(this.content)
}
space() {
this.content+= ' '
}
readOperator() {
console.log(this.operator)
}
run(...args) {
this.operator.push(args[0])
this[args[0]].apply(this, args.slice(1))
return this
}
}
const editor = new Editor()
editor.run('write', 'hello').run('space').run('write', 'zkk!').run('read') // => 'hello zkk!'
// 输出操作队列
editor.readOperator() // ["write", "space", "write", "read"]
通过这种模式,我们可以把所有命令包裹在一个方法中,进行统一的管理,用户也不需要关心类内部具体实现的变动,只需通过对应的命令参数就可以操作新添加的方法。实现行为请求者与行为实现者的解耦。
与此同时,我们可以对用户所有的操作记录进行队列维护,解决撤销、多人编辑等的问题。
当然,实际上要比实例复杂的多,通常也会把调用者Invoker和命令子类Command分开维护,增强可扩展性。