命令模式是對象行為型使用率比較高的設計模式,別名:Action(動作),Transaction(事務)
意圖: 將一個請求封裝為一個對象,從而使你可對不同的請求進行參數化;對請求排隊或記錄請求日志,以及支持可取消的操作
這里所謂的“不同的請求”也既意味著請求可能發生的變化,是一個可能擴展的功能點。
動機: 方便擴展
結構:
協作說明:
參與角色:
Command 聲明一個接口以用來實現某個操作。
ConcreteCommand 將動作與Reciver對外綁定,通過調用Reciver對象的相應方法來實現Command的方法。
Client 創建ConcreteCommand對象,并設置其Reciver對象。
Invoker 要求該Command實現請求。
Reciver 知道如何實現具體的請求的類。
客戶端創建了一個具體的Command對象并指定了其接收者。
調用者對象存儲了此具體的Command對象。
調用者對象通過執行Command對象的Execute方法來實現當前請求。
如果命令是可以撤銷時,具體對象在調用執行方法前將存儲相應的狀態以用來命令此請求。
具體的Command對象調用其接收者的方法從而來實現相應請求。
適用性:
類似于 MenuItem , 抽象出待執行的動作以參數化某對象
在不同的時刻指定,排列,執行請求
支持撤消
支持修改日志
在構建在原語操作上的高層操作構造一個系統(其實就是事務)
動態性方面: 像ruby中 block 就是命令模式
效果:
命令模式將調用者對象與接收對象解耦(調用與實現解耦)。調用者實現功能時只需調用Command接口的Execute方法。
具體的Commands對象是第一層對象,它們可以像其他對象一樣被擴展或操作。
你可以將多個Commands對象聚合成一個組合命令。組合命令也是組合對象模式的一個實例,將命令排隊也是其的一種特殊情況。
你可以很容易的添加新的命令,因為你并不需要修改現有的代碼。這也符合了開閉原則,對修改關閉,對擴展開放。
實現時應考慮命令對象應達到何種智能程序和支持撤消和重做這兩個問題.
誤用:
不要著迷 到底哪個簡單?
命令模式不是說“做這個” 說“ 記住這個如何做”,稍后再說”按照我剛才要你記住的方法做這個”
小心撤銷,許多操作是破壞性的,如刪除文件操作
類圖:
class Button attr_accessor :name, :command def initialize name, command @name = name @command = command end def do_something @command.execute end endclass Command def execute "root execute" end endclass PaintCommand < Command def execute "draw something" end endclass VocalCommand < Command def execute "talk something" end endpaintCommand = PaintCommand.newvocalCommand = VocalCommand.newbutton = Button.new("button", paintCommand)p button.do_somethingbutton.command = vocalCommandp button.do_something
新聞熱點
疑難解答