意圖:將一個請求封裝爲一個對象,從而可用不一樣的請求對客戶進行參數化;對請求排隊或記錄日誌,以及支持可撤銷的操做
動機:將」發出請求的對象」和」接收與執行這些請求的對象」分隔開來。
效果:
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