問題描述
一個消息的發送者對象向消息的接收者發送消息,發送者如果保持接收者的信息,即可完成消息的投遞。但是這種方式把消息的發送者和接收者直接綁定在一起,讓消息的發送者依賴於消息的接收者。命令模式解除了消息發送者對於消息接收者的依賴。
命令模式
如圖所示,命令模式引入了一個間接層即Command對象來隔離消息發送者Invoker對象和消息的接收者對象Receiver。客戶把一個消息接收者對象Receiver註冊到一個Command對象中,以便Command對象Execute()方法轉發一個消息給該接收者。客戶利用一個Command對象來參數化消息發送者Invoker對象,當Invoker對象檢測到消息需要發送的時候,投遞該消息到Command對象。在Invoker對象看來,Command對象封裝了消息的接收者信息(包括接收者的類型,消息接收方法等);Invoker對象只需要與一個穩定的Command接口交互,而不需要關注消息接收者的信息。除了消息投遞,Command對象Execute()方法可以完成其他操作,例如:
- 決定是否轉發該消息到 Receiver對象
- 依據ConcreteCommand和Receiver的約定,Execute()方法也可以調用Receiver的多個方法來完成一個消息的接收工作
- 利用Memento備忘錄模式,ConcreteCommand對象甚至可以支持一個命令的撤銷:即依據備忘信息來恢復Receiver對象在執行命令前的狀態。
討論
命令模式在消息的發送者和接收者之間引入了一個間接層次,即Command對象;解除了消息的發送者和接收者的直接依賴關係;消除了消息發送者和消息接收邏輯之間的依賴關係。