• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>

            大龍的博客

            常用鏈接

            統計

            最新評論

            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 2011-01-09 14:00 大龍 閱讀(385) 評論(0)  編輯 收藏 引用

            日韩精品国产自在久久现线拍| 免费久久人人爽人人爽av| 99久久99久久精品免费看蜜桃| 97久久超碰国产精品旧版| A级毛片无码久久精品免费| 色综合合久久天天给综看| 久久免费的精品国产V∧| 久久99精品国产麻豆宅宅| 久久久久亚洲精品天堂久久久久久| 漂亮人妻被中出中文字幕久久| 嫩草伊人久久精品少妇AV| 国产99久久久久久免费看| 思思久久好好热精品国产| 久久亚洲综合色一区二区三区| 久久性生大片免费观看性| 国产午夜精品久久久久免费视 | 精品999久久久久久中文字幕| 久久播电影网| 久久精品国产亚洲欧美| 精品久久久无码21p发布| 久久国产成人午夜aⅴ影院 | 久久九色综合九色99伊人| 亚洲国产精品一区二区久久hs| 久久综合一区二区无码| 精品久久久久久国产免费了| 久久婷婷五月综合97色一本一本 | 国产精品午夜久久| 久久精品国内一区二区三区| 午夜天堂av天堂久久久| 久久久精品人妻一区二区三区蜜桃 | 精品久久人人爽天天玩人人妻| 久久久国产精华液| 99久久99久久精品国产片果冻| 久久久久亚洲精品天堂| 久久精品国产亚洲AV香蕉| 一本久久知道综合久久| 青青草原综合久久大伊人| 久久精品亚洲AV久久久无码| 99久久夜色精品国产网站| 亚洲精品tv久久久久久久久| 久久久噜噜噜久久中文福利|