設計模式之命令模式

命令模式(Command),其含義是將一個請求封裝爲一個對象,從而使你可用不一樣的請求對客戶進行參數化;對請求排隊或記錄請求日誌,以及支持可撤銷的操做。命令模式經過將請求自己變成一個對象來使工具箱對象可向未指定的應用對象提出請求,這個對象可被存儲並像其餘的對象同樣被傳遞。ide

其適用性:函數

若是想抽象出待執行的動做以參數化某對象,可用回調函數表達這種參數化機制。所謂回調函數是指函數先在某處註冊,而它將在稍後某個須要的時候被調用。Command模式是回調機制的一個面向對象的替代品,工具

在不一樣的時刻指定、排列和執行請求。一個Command對象能夠有一個與初始請求無關的生存期。若是一個請求的接受者可用一種與地址空間無關的方式表達,那麼就可將負責該請求的命令對象傳送給另外一個不一樣的進程並在那兒實現該請求。(好深奧,求解釋) 測試

支持取消操做。Command的Execute操做可在實施操做前將狀態存儲起來,在取消操做時這個狀態用來消除該操做的影響。Command接口必須添加一個Unexecute操做,該操取消上一次Execute調用的效果。執行的命令被存儲在一個歷史列表中。可經過向後和向前遍歷這一列表並分別調用Unexecute和Execute來實現重數不限的「取消」和「重作」。this

支持修改日誌,這樣當系統崩潰時,這些修改能夠被重作一遍。在Command接口中添加裝載操做和存儲操做,能夠用來保持變更的一個一致的修改日誌。從崩潰中回覆的過程包括從磁盤中從新讀入記錄下來的命令並用Execute操做從新執行它們,spa

用構建在原語操做上的高層操做構造一個系統。這樣一種結構在支持事務的信息系統中很常見。一個事務封裝了對數據的一組變更。Command模式提供了對事務進行建模的方法。Command有一個公共的接口,使得你能夠用同一種方式調用全部的事務。同時使用該模式也易於添加新事物以擴展系統。日誌

其結構圖爲:code

           

客戶端發過來的請求被封裝成Command對象,並指定了它的Receiver對象,某個Invoker對象存儲該ConcreteCommand對象。該Invoker經過調用Command對象的Execute操做來提交一個請求 (若是該命令是可撤銷的,ConcreteCommand就在執行Execute操做以前存儲當前狀態以用於取消該命令)。ConcreteCommand對象對調用它的Receiver的一些操做以執行該請求。對象

 該模式的實現較爲簡單,Command類是一個抽象類,也能夠是一個接口,ConcreteCommand類以下:blog

  package  org.designpattern.behavioral.command;
public  class ConcreteCommandA  extends Command {

     public ConcreteCommandA(Receiver receiver){
         super(receiver);
    }
    @Override
     public  void execute() {
         // To change body of implemented methods use File | Settings | File Templates.
         this.receiver.action();
        System.out.println("command executed!");
    }
}

 每一個Command都會指定一個Invoker實例,由其來提交請求:

package  org.designpattern.behavioral.command;
public  class Invoker {
     private Command command;

     public Invoker(Command command){
         this.command = command;
    }
     public  void invoke(){
        System.out.println("command invoked!");
         this.command.execute();
    }

} 

具體的請求的執行是由Receiver回調函數來執行的:

package  org.designpattern.behavioral.command;
public  class Receiver {
     public  void action(){
        System.out.println("command received!");
    }

} 

  客戶測試類以下:

package  org.designpattern.behavioral.command;
public  class Main {
     public  static  void main(String[] args) {
        Receiver receiver =  new Receiver();
        Command command =  new ConcreteCommandA(receiver);
        Invoker invoker =  new Invoker(command);
        invoker.invoke();
    }

} 

 命令模式把請求一個操做的對象與知道怎麼執行一個操做的對象分隔開,即「行爲請求者」與「行爲實現者」之間緊密耦合的問題,可與其餘模式相結合使用,如組合模式、備忘錄模式等。

相關文章
相關標籤/搜索