什麼是命令模式?
命令模式(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分開維護,增強可擴展性。