命令模式

意圖:將一個請求封裝爲一個對象,從而可用不一樣的請求對客戶進行參數化;對請求排隊或記錄日誌,以及支持可撤銷的操做
動機:將」發出請求的對象」和」接收與執行這些請求的對象」分隔開來。
效果:
1)、command模式將調用操做的對象和實現該操做的對象解耦
2)、能夠將多個命令裝配成一個複合命令,複合命令是Composite模式的一個實例
3)、增長新的command很容易,無需改變已有的類
適用性:
1)、抽象出待執行的動做以參數化某對象
2)、在不一樣的時刻指定、排列和執行請求。如請求隊列
3)、支持取消操做
4)、支持修改日誌
5)、用構建在原語操做上的高層操做構造一個系統。支持事物
參與者:
1)、Command
  聲明執行操做的接口
2)、ConcreteCommand
  將一個接收者對象綁定於一個動做
  調用接收者相應的操做,以實現execute
3)、Client
  建立一個具體命令對象並設定它的接收者
4)、Invoker
  要求該命令執行這個請求
5)、Receiver
  知道如何實施與執行一個請求相關的操做。任何類均可能做爲一個接收者
結構圖:ide

協做:
1)、client建立一個ConcreteCommand對象並指定它的Receiver對象
2)、某Invoker對象存儲該ConcreteCommand對象
3)、該Invoker經過調用Command對象的execute操做來提交一個請求。若該命令是可撤銷的,ConcreteCommand在執行execute操做前存儲當前狀態以用於取消該命令
4)、ConcreteCommand對象調用它的Receiver的操做以執行該請求
命令對象將動做和接受者包進對象中,這個對象只暴露出一個execute()方法,當此方法被調用的時候,接收者就會進行這些動做。從外面來看,其餘對象不知道究竟哪一個接收者進行了哪些動做,只知道若是調用execute()方法,請求的目的就能達到。 測試

實例:this

複製代碼
 1 package com.test.patten.command;
 2 
 3 /**
 4  * 命令接口
 5  */
 6 public interface Command {
 7     /**
 8      * 執行命令
 9      */
10     public void execute();
11     /**
12      * 撤銷命令
13      */
14     public void undo();
15 }
複製代碼
複製代碼
 1 package com.test.patten.command;
 2 
 3 /**
 4  * 命令
 5  */
 6 public class CreateCommand implements Command{
 7     private Receiver receiver;
 8     private String state;
 9     
10     public CreateCommand(Receiver receiver){
11         this.receiver = receiver;
12     }
13 
14     @Override
15     public void execute() {
16         receiver.action();
17     }
18 
19     @Override
20     public void undo() {
21         receiver.unAction();
22     }
23     
24 }
複製代碼
複製代碼
 1 package com.test.patten.command;
 2 
 3 /**
 4  * 命令接收者,命令真正執行人
 5  */
 6 public class Receiver {
 7     public void action(){
 8         System.out.println("執行命令...");
 9     }
10     
11     public void unAction(){
12         System.out.println("撤銷命令...");
13     }
14 }
複製代碼
複製代碼
 1 package com.test.patten.command;
 2 
 3 public class Invoker {
 4     /**
 5      * 調用者持有命令對象
 6      */
 7     private Command command;
 8 
 9     /**
10      * 設置命令對象
11      * @param command
12      */
13     public void setCommand(Command command) {
14         this.command = command;
15     }
16     public Command getCommand() {
17         return command;
18     }
19 
20     /**
21      * 執行命令
22      */
23     public void runCommand(){
24         command.execute();
25     }
26     /**
27      * 撤銷命令
28      */
29     public void unDoCommand(){
30         command.undo();
31     }
32 }
複製代碼
複製代碼
 1 package com.test.patten.command;
 2 
 3 public class Client {
 4     public static void main(String[] args){
 5         //建立接受者
 6         Receiver receiver = new Receiver();
 7         //建立命令對象,並設置它的接受者
 8         Command command = new CreateCommand(receiver);
 9         
10         //建立調用者,將命令對象設置進去
11         Invoker invoker = new Invoker();
12         invoker.setCommand(command);
13         
14         //這裏能夠測試一下
15         invoker.runCommand();
16         invoker.unDoCommand();
17     }
18 }
複製代碼

常見應用:
一、工做隊列,線程池,日程安排
二、日誌請求(系統恢復)
要點:
一、命令模式將發出請求的對象和執行請求的對象解耦
二、在被解耦的二者之間是經過命令對象進行溝通的。命令對象封裝了接收者和一個或一組動做
三、調用者經過調用命令對象的execute()發出請求,這會使得接收者的動做被調用
四、調用者能夠接受命令看成參數,甚至在運行時動態的進行
五、命令能夠支持撤銷,作法是實現一個undo()方法來回到execute()被執行前的狀態
六、宏命令是命令的一種簡單的延伸,容許調用多個命令。宏方法也能夠支持撤銷
七、實際操做時,很常見使用"聰明"命令對象,也就是直接實現了請求,而不是將工做委託給接受者(弊端?)
八、命令也能夠用來實現日誌和事物系統spa

相關文章
相關標籤/搜索
本站公眾號
   歡迎關注本站公眾號,獲取更多信息