《JAVA與模式》之命令模式

來源:互聯網
上載者:User
文章目錄
  • 原始碼
  •   原始碼

在閻宏博士的《JAVA與模式》一書中開頭是這樣描述命令(Command)模式的:

  命令模式屬於對象的行為模式。命令模式又稱為行動(Action)模式或交易(Transaction)模式。

  命令模式把一個請求或者操作封裝到一個對象中。命令模式允許系統使用不同的請求把用戶端參數化,對請求排隊或者記錄請求日誌,可以提供命令的撤銷和恢複功能。

命令模式的結構

  命令模式是對命令的封裝。命令模式把發出命令的責任和執行命令的責任分割開,委派給不同的對象。

  每一個命令都是一個操作:請求的一方發出請求要求執行一個操作;接收的一方收到請求,並執行操作。命令模式允許請求的一方和接收的一方獨立開來,使得請求的一方不必知道接收請求的一方的介面,更不必知道請求是怎麼被接收,以及操作是否被執行、何時被執行,以及是怎麼被執行的。

  命令允許請求的一方和接收請求的一方能夠獨立演化,從而具有以下的優點:

  (1)命令模式使新的命令很容易地被加入到系統裡。

  (2)允許接收請求的一方決定是否要否決請求。

  (3)能較容易地設計一個命令隊列。

  (4)可以容易地實現對請求的撤銷和恢複。

  (5)在需要的情況下,可以較容易地將命令記入日誌。

  下面以一個示意性的系統,說明命令模式的結構。

  命令模式涉及到五個角色,它們分別是:

  ●  用戶端(Client)角色:建立一個具體命令(ConcreteCommand)對象並確定其接收者。

  ●  命令(Command)角色:聲明了一個給所有具體命令類的抽象介面。

  ●  具體命令(ConcreteCommand)角色:定義一個接收者和行為之間的弱耦合;實現execute()方法,負責調用接收者的相應操作。execute()方法通常叫做執行方法。

  ●  要求者(Invoker)角色:負責調用命令對象執行請求,相關的方法叫做行動方法。

  ●  接收者(Receiver)角色:負責具體實施和執行一個請求。任何一個類都可以成為接收者,實施和執行請求的方法叫做行動方法。

原始碼

  接收者角色類

public class Receiver {    /**     * 真正執行命令相應的操作     */    public void action(){        System.out.println("執行操作");    }}

  抽象命令角色類

public interface Command {    /**     * 執行方法     */    void execute();}

  具體命令角色類

public class ConcreteCommand implements Command {    //持有相應的接收者對象    private Receiver receiver = null;    /**     * 構造方法     */    public ConcreteCommand(Receiver receiver){        this.receiver = receiver;    }    @Override    public void execute() {        //通常會轉調接收者對象的相應方法,讓接收者來真正執行功能        receiver.action();    }}

  要求者角色類

public class Invoker {    /**     * 持有命令對象     */    private Command command = null;    /**     * 構造方法     */    public Invoker(Command command){        this.command = command;    }    /**     * 行動方法     */    public void action(){                command.execute();    }}

  用戶端角色類

public class Client {    public static void main(String[] args) {        //建立接收者        Receiver receiver = new Receiver();        //建立命令對象,設定它的接收者        Command command = new ConcreteCommand(receiver);        //建立要求者,把命令對象設定進去        Invoker invoker = new Invoker(command);        //執行方法        invoker.action();    }}

 

AudioPlayer系統

  小女孩茱麗(Julia)有一個盒式錄音機,此錄音機有播音(Play)、倒帶(Rewind)和停止(Stop)功能,錄音機的鍵盤便是要求者(Invoker)角色;茱麗(Julia)是用戶端角色,而錄音機便是接收者角色。Command類扮演抽象命令角色,而PlayCommand、StopCommand和RewindCommand便是具體命令類。茱麗(Julia)不需要知道播音(play)、倒帶(rewind)和停止(stop)功能是怎麼具體執行的,這些命令執行的細節全都由鍵盤(Keypad)具體實施。茱麗(Julia)只需要在鍵盤上按下相應的鍵便可以了。

  錄音機是典型的命令模式。錄音機按鍵把用戶端與錄音機的操作細節分割開來。

  

  原始碼

  接收者角色,由錄音機類扮演

public class AudioPlayer {        public void play(){        System.out.println("播放...");    }        public void rewind(){        System.out.println("倒帶...");    }        public void stop(){        System.out.println("停止...");    }}

  抽象命令角色類

public interface Command {    /**     * 執行方法     */    public void execute();}

  具體命令角色類

public class PlayCommand implements Command {    private AudioPlayer myAudio;        public PlayCommand(AudioPlayer audioPlayer){        myAudio = audioPlayer;    }    /**     * 執行方法     */    @Override    public void execute() {        myAudio.play();    }}
public class RewindCommand implements Command {    private AudioPlayer myAudio;        public RewindCommand(AudioPlayer audioPlayer){        myAudio = audioPlayer;    }    @Override    public void execute() {        myAudio.rewind();    }}
public class StopCommand implements Command {    private AudioPlayer myAudio;        public StopCommand(AudioPlayer audioPlayer){        myAudio = audioPlayer;    }    @Override    public void execute() {        myAudio.stop();    }}

  要求者角色,由鍵盤類扮演

public class Keypad {    private Command playCommand;    private Command rewindCommand;    private Command stopCommand;        public void setPlayCommand(Command playCommand) {        this.playCommand = playCommand;    }    public void setRewindCommand(Command rewindCommand) {        this.rewindCommand = rewindCommand;    }    public void setStopCommand(Command stopCommand) {        this.stopCommand = stopCommand;    }    /**     * 執行播放方法     */    public void play(){        playCommand.execute();    }    /**     * 執行倒帶方法     */    public void rewind(){        rewindCommand.execute();    }    /**     * 執行播放方法     */    public void stop(){        stopCommand.execute();    }}

  用戶端角色,由茱麗小女孩扮演

public class Julia {    public static void main(String[]args){        //建立接收者對象        AudioPlayer audioPlayer = new AudioPlayer();        //建立命令對象        Command playCommand = new PlayCommand(audioPlayer);        Command rewindCommand = new RewindCommand(audioPlayer);        Command stopCommand = new StopCommand(audioPlayer);        //建立要求者對象        Keypad keypad = new Keypad();        keypad.setPlayCommand(playCommand);        keypad.setRewindCommand(rewindCommand);        keypad.setStopCommand(stopCommand);        //測試        keypad.play();        keypad.rewind();        keypad.stop();        keypad.play();        keypad.stop();    }}

運行結果如下:

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.