<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    DANCE WITH JAVA

    開發出高質量的系統

    常用鏈接

    統計

    積分與排名

    好友之家

    最新評論

    Java中的模式 --- 命令模式的(實現,功能,使用場合)及如何配合其它模式使用命令模式

    一,命令模式的實現:
    命令模式里邊一般都有以下幾個角色:客戶端,請求者,命令接口,命令實現,接受者,
    下邊是簡單命令模式的實現代碼實現:
     1public class Client{
     2    public static void main(String[] args){
     3        Receiver receiver = new Receiver();
     4        Command commandOne = new ConcreteCommandOne(receiver);
     5        Command commandTwo = new ConcreteCommandTwo(receiver);
     6        Invoker invoker = new Invoker(commandOne,commandTwo);
     7        invoker.actionOne();
     8        invoker.actionTwo();
     9    }

    10}

    11public class Invoker{
    12    private Command commandOne;
    13    private Command commandTwo;
    14    public Invoker(Command commandOne,Command commandTwo){
    15        this.commandOne = commandOne;
    16        this.commandTwo = commandTwo;
    17    }

    18    public void actionOne(){
    19        commandOne.execute();
    20    }

    21    public void actionTwo(){
    22        commandTwo.execute();
    23    }

    24}

    25public interface Command{
    26    void execute();
    27}

    28public class ConcreteCommandOne implements Command{
    29    private Receiver receiver
    30    public ConcreteCommandOne(Receiver receiver){
    31        this.receiver = receiver;
    32    }

    33    public void execute(){
    34        receiver.actionOne();
    35    }

    36}

    37public class ConcreteCommandTwo implements Command{
    38    private Receiver receiver
    39    public ConcreteCommandTwo(Receiver receiver){
    40        this.receiver = receiver;
    41    }

    42    public void execute(){
    43        receiver.actionTwo();
    44    }

    45}

    46public class Receiver{
    47    public Receiver(){
    48        //
    49    }

    50    public void actionOne(){
    51        System.out.println("ActionOne has been taken.");
    52    }

    53    public void actionTwo(){
    54        System.out.println("ActionTwo has been taken.");
    55    }

    56}

    二,命令模式的功能,好處,或者說為什么使用命令模式?
    上邊的代碼是否看起來很傻呢,本來可以這樣簡單實現的:
     1public class Client{
     2    public static void main(String[] args){
     3        Receiver receiver = new Receiver();
     4        receiver.actionOne();
     5        receiver.actionTwo();
     6    }

     7}

     8public class Receiver{
     9    public Receiver(){
    10        //
    11    }

    12    public void actionOne(){
    13        System.out.println("ActionOne has been taken.");
    14    }

    15    public void actionTwo(){
    16        System.out.println("ActionTwo has been taken.");
    17    }

    18}


    看多簡潔,如果是像上邊如此簡單的需求,這個才應該是我們的選擇,但是有些情況下這樣的寫法不能解決的,
    或者說解決起來不好,所以引入命令模式.
    (1)我們須要Client和Receiver同時開發,而且在開發過程中分別須要不停重購,改名
    (2)如果我們要求Redo ,Undo等功能
    (3)我們須要命令不按照調用執行,而是按照執行時的情況排序,執行
    (4)開發后期,我們發現必須要log哪些方法執行了,如何在盡量少更改代碼的情況下實現.并且漸少重復代碼
    (5)在上邊的情況下,我們的接受者有很多,不止一個
    解決辦法:
    情況一,我們可以定義一個接口,讓Receiver實現這個接口,Client按照接口調用。
    情況二,我們可以讓Receiver記住一些狀態,例如執行前的自己的狀態,用來undo,但自己記錄自己的狀態
     實現起來比較混亂,一般都是一個累記錄另一個類的狀態.
    情況三,很難實現
    情況四,,我們須要在每個Action,前后加上log
    情況五,相對好實現,但是再加上這個,是否感覺最終的實現很混亂呢
    好,我們再來看看命令模式,在命令模式中,我們增加一些過渡的類,這些類就是上邊的命名接口和命令實現,
    這樣就很好的解決了情況一,情況二。我們再加入一個Invoker,這樣情況三和情況四就比較好解決了。

    如下加入Log和排序后的Invoker

     1public class Invoker{
     2    private List cmdList = new ArrayList();
     3    public Invoker(){
     4    }

     5    public add(Command command){
     6        cmdList.add(command);
     7    }

     8    public remove(Command command){
     9        cmdList.remove(command);
    10    }

    11    public void action(){
    12        Command cmd;
    13        while((cmd =getCmd()) != null){
    14            log("begin"+cmd.getName());
    15            cmd.execute();
    16            log("end"+cmd.getName());        
    17        }

    18    }

    19    public Command getCmd(){
    20        //按照自定義優先級,排序取出cmd
    21    }

    22}

    23public class Client{
    24    public static void main(String[] args){
    25        Receiver receiver = new Receiver();
    26        Command commandOne = new ConcreteCommandOne(receiver);
    27        Command commandTwo = new ConcreteCommandTwo(receiver);
    28        Invoker invoker = new Invoker();
    29        invoker.add(commandOne);
    30        invoker.add(commandTwo);
    31        iinvoker.action();
    32    }

    33}


    三,命令模式與其它模式的配合使用:
    1,看上邊的Invoker的實現是否很像代理模式呢,Invoker的這種實現其實就是一種代理模式。

    2,需求:有個固定命令組合會多次被執行
       解決:加入合成模式,實現方法如下,定義一個宏命令類:

     1public class MacroCommand implements Command{
     2    private List cmdList = new ArrayList();
     3    public add(Command command){
     4        cmdList.add(command);
     5    }

     6    public remove(Command command){
     7        cmdList.remove(command);
     8    }

     9    public void execute(){
    10        Command cmd;
    11        for(int i=0;i<cmdList.size();i++){
    12            cmd = (Command)cmdList.get(i);
    13            cmd.execute();
    14        }

    15    }
        
    16}

    3,需求:須要redo undo
      解決:加入備忘錄模式,一個簡單的實現如下
     1public class ConcreteCommandOne implements Command{
     2    private Receiver receiver
     3    private Receiver lastReceiver;
     4    public ConcreteCommandOne(Receiver receiver){
     5        this.receiver = receiver;
     6    }

     7    public void execute(){
     8        record();
     9        receiver.actionOne();
    10    }

    11    public void undo(){
    12        //恢復狀態
    13    }

    14    public void redo(){
    15        lastReceiver.actionOne();
    16        //
    17    }

    18    public record(){
    19        //記錄狀態
    20    }

    21}

    4,需求:命令很多類似的地方
       解決:使用原型模式,利用clone
       這個就不寫例子了。
    四,命令模式的使用場合
    1,須要callback的時候,例如java awt/swing/swt中的Listening的消息方式
    2,須要對請求排隊執行,命令的發送者和接受者有不同對的生命周期,就是命令執行的時候,可能發出命令的
    Client已經不存在了
    3,須要Redo Undo等函數
    4,須要log每條命令
    5,須要支持transaction,封裝一組數據命令的時候.
    五,最后再次總結一下命令模式的優點和缺點:
    優點:
    降低Client和命令接受者的耦合,是命令請求和命令執行的對象分割
    便于修改和擴張
    便于聚合多個命令
    缺點:
    造成出現過多的具體命令類,太多文件。

    五,一個比較有意思的例子,來說明命令模式
    Client        :看電視的人
    Invoker     :遙控器
    Command :電信號
    具體命令 :遙控器上的按鍵對應的不同的電信號
    Receiver    :電視機
    最后說一句,并不是全部按照模式寫一定就好,應該根據你的需求來應用,或者全部應用,或者部分應用,或者根本不用。

    posted on 2006-11-27 02:31 dreamstone 閱讀(3566) 評論(3)  編輯  收藏 所屬分類: 設計模式

    評論

    # re: Java中的模式 --- 命令模式的(實現,功能,使用場合)及如何配合其它模式使用命令模式 2006-11-27 17:21 Tony[匿名]

    寫到太好了,清楚直接。謝謝~  回復  更多評論   

    # re: Java中的模式 --- 命令模式的(實現,功能,使用場合)及如何配合其它模式使用命令模式 2007-08-07 12:35 hh

    寫的不錯!!  回復  更多評論   

    # re: Java中的模式 --- 命令模式的(實現,功能,使用場合)及如何配合其它模式使用命令模式 2009-06-19 15:39 estone

    看過你的很多文章,受益匪淺,謝謝!  回復  更多評論   

    主站蜘蛛池模板: 亚洲精品成人无限看| 手机看黄av免费网址| 久久久久亚洲精品日久生情 | 亚洲一区二区三区偷拍女厕 | 久久夜色精品国产嚕嚕亚洲av| 亚洲乱码国产乱码精品精| selaoban在线视频免费精品| 无码人妻精品中文字幕免费 | 亚洲午夜久久久久久久久电影网| 日韩毛片在线免费观看| 亚洲 综合 国产 欧洲 丝袜| 久久亚洲精品成人无码网站| 99热这里只有精品6免费| 免费乱码中文字幕网站| 在线视频亚洲一区| 精品乱子伦一区二区三区高清免费播放| 巨波霸乳在线永久免费视频| 亚洲另类古典武侠| 中文在线免费观看| 免费观看国产小粉嫩喷水| 亚洲精品日韩专区silk| 99精品免费视频| 久久久久亚洲精品天堂| 中国在线观看免费国语版| 亚洲A∨精品一区二区三区下载 | 无码免费一区二区三区免费播放| 久久夜色精品国产噜噜亚洲AV| 成人免费一级毛片在线播放视频| 亚洲AV无码XXX麻豆艾秋| 久久国产成人精品国产成人亚洲 | 久久久久久国产精品免费无码| 中文字幕在亚洲第一在线| 两个人看的www免费高清| 亚洲成人高清在线观看| 久久永久免费人妻精品下载| 99热亚洲色精品国产88| 18禁网站免费无遮挡无码中文 | 2017亚洲男人天堂一| 亚洲区小说区图片区| 亚洲av乱码中文一区二区三区| 亚洲一区无码精品色|