<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

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

    主站蜘蛛池模板: 在线观看免费视频一区| 亚洲人成网站免费播放| 亚洲国产精品yw在线观看| 大陆一级毛片免费视频观看i| 美女被免费视频网站| 国产∨亚洲V天堂无码久久久| 成年人网站免费视频| 一级毛片**免费看试看20分钟| 亚洲一区中文字幕久久| 国产hs免费高清在线观看| 未满十八18禁止免费无码网站| 亚洲精品无码久久久久YW| 中文字幕精品亚洲无线码一区| 丁香花在线观看免费观看| 成人片黄网站色大片免费观看cn| 亚洲人成片在线观看| 亚洲日韩精品无码专区网站 | 久久精品国产亚洲av天美18| 亚洲人精品午夜射精日韩| 最近最好的中文字幕2019免费 | 亚洲熟女www一区二区三区| 亚洲熟女乱综合一区二区| 无码人妻一区二区三区免费手机| av网站免费线看| 亚洲成a人片在线不卡| 精品亚洲综合在线第一区| www国产亚洲精品久久久日本| 91精品免费久久久久久久久| 韩国免费a级作爱片无码| 亚洲国产AV一区二区三区四区| 亚洲一区二区在线免费观看| 在线亚洲人成电影网站色www| 国产男女性潮高清免费网站 | 免费无码AV片在线观看软件| 日本一道本不卡免费 | 国产自产拍精品视频免费看| 希望影院高清免费观看视频| 免费观看久久精彩视频| 国产VA免费精品高清在线| 亚洲GV天堂无码男同在线观看| 亚洲人成网站日本片|