標籤:
命令模式 1 使用情境 1. 命令的寄件者和命令執行者有不同的生命週期。命令發送了並不是立即執行。
2. 命令需要進行各種管理邏輯。
3. 需要支援撤消\重做操作(撤銷命令)。
2 角色 2.1 client 1、建立具體的命令
2、設定命令的接受者
2.2 Command 1 定義命令的統一介面
2 command為所有命令聲明了一個借口,調用命令對象的excute方法,就可以讓接受者進行相關的操作
3 這個介面也具備撤銷的方法
2.3 ConcreteCommand 1 Command介面的實現者,用來執行具體的命令,某些情況下可以直接用來充當Receiver。
2 具體命令會調用接受者的動作,以滿足請求
2.4 invoker 1 命令的實際執行者
2 這個調用者持有一系列命令對象,並在某個時間調用命令對象的excute方法,將請求付諸實行。
2.5 Receiver 1 命令的要求者,是命令模式中最重要的角色。這個角色用來對各個命令進行控制。
2 命令對象通過在特定接受者上綁定一組動作來封裝一個請求
3 接受者有多個
4 接受者經常通過參數化對象來綁定到具體命令對象中
5 接受者知道如何進行必要的工作,實現這個請求,任何類都可以當接受者
6 一般情況下,一個具體命令對應一個具體的接受者
3 例子 3.1 客戶向服務員點餐-服務員將菜單交給廚師,廚師烹飪各種食物
3.2 使用命令模式的一般步驟
1 第一步:初始化所有的接受者
2 第二步:建立所有的命令對象
3 第三步:調用者載入命令
4 第四步:在適當的時候讓調用者執行命令
3.3 demo
package limanman;import java.util.ArrayList;import java.util.List;public class CommandTest {public static void main(String[] args) {Client.run();}}class Client {public static void run() {/** * 第一步:初始化所有的接受者 */Receiver1 receiver1 = new Receiver1();Receiver2 receiver2 = new Receiver2();/** * 第二步:建立所有的命令對象 */Command command1 = new ConcreateCmonmand1(receiver1);Command command2 = new ConcreateCmonmand2(receiver2);/** * 第三步:調用者載入命令 */Invoker invoker = new Invoker();invoker.setCommand(command1);invoker.setCommand(command2);/** * 第四步:在適當的時候讓調用者執行命令 */invoker.callRecever(0);invoker.callRecever(1);}}/** * 接受者1,一個具體命令對應一個具體接收者 * * @author limanman * @date 2015年10月12日 */class Receiver1 {public void action() {System.out.println("接收者1執行具體的操作");}}/** * 接受者2,一個具體命令對應一個具體接收者 * * @author limanman * @date 2015年10月12日 */class Receiver2 {public void action() {System.out.println("接收者2執行具體的操作");}}/** * 命令角色 * * @author limanman * @date 2015年10月12日 */interface Command {public void excute();}/** * 角色: 具體命令 * * @author limanman * @date 2015年10月12日 */class ConcreateCmonmand1 implements Command {Receiver1 receiver1;public ConcreateCmonmand1(Receiver1 receiver1) {this.receiver1 = receiver1;}@Overridepublic void excute() {System.out.println("執行命令1");receiver1.action();}}class ConcreateCmonmand2 implements Command {Receiver2 receiver2;public ConcreateCmonmand2(Receiver2 receiver2) {this.receiver2 = receiver2;}@Overridepublic void excute() {System.out.println("執行命令2");receiver2.action();}}/** * 角色:invoker * * @author limanman * @date 2015年10月12日 */class Invoker {List<Command> commands = new ArrayList<Command>();/** * 設定命令 * * @param command * @date 2015年10月12日 * @author 佚名 */public void setCommand(Command command) {commands.add(command);}/** * 調用者持有一系列命令對象,並在某個時間點調用對象的excute方法,將請求付諸實行 * * @param slot * @date 2015年10月12日 * @author 佚名 */public void callRecever(int slot) {commands.get(slot).excute();}}
輸出:
執行命令1
接受者1執行具體的操作
執行命令2
接受者2執行具體的操作
4 要點 1 命令模式是通過命令寄件者和命令執行者的解耦來完成對命令的具體控制的。
2 命令模式是對功能方法的抽象,並不是對對象的抽象。
3 命令模式是將功能提升到對象來操作,以便對多個功能進行一系列的處理以及封裝。
5 設計原則 對修改封閉,對擴充開放
6 核心 1 參數化對象,對象中包含請求和具體的操作
2 要求者建立命令和接受者,接受者執行命令和撤銷命令
7 定義 "請求"封裝成對象,以便使用不同的請求,隊列或者日誌來參數化其他對象,命令模式也支援可撤銷的操作
8 好處 1.更方便的對命令進行擴充
2.對多個命令的統一控制
3.支援撤銷操作
9 問題 9.1 命令模式的設計如何支援要求者和請求接受者之間的解耦
1、invoker只是包含了抽象的命令(interface)
2、具體的命令和接受者跟invoker沒有直接的關聯
設計模式系列之命令模式