• <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>

            大龍的博客

            常用鏈接

            統(tǒng)計(jì)

            最新評(píng)論

            Java中的模式 --- 命令模式的(實(shí)現(xiàn),功能,使用場(chǎng)合)

            一,命令模式的實(shí)現(xiàn):
            命令模式里邊一般都有以下幾個(gè)角色:客戶端,請(qǐng)求者,命令接口,命令實(shí)現(xiàn),接受者,
            下邊是簡(jiǎn)單命令模式的實(shí)現(xiàn)代碼實(shí)現(xiàn):  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}
            二,命令模式的功能,好處,或者說(shuō)為什么使用命令模式?
            上邊的代碼是否看起來(lái)很傻呢,本來(lái)可以這樣簡(jiǎn)單實(shí)現(xiàn)的:
             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}

            看多簡(jiǎn)潔,如果是像上邊如此簡(jiǎn)單的需求,這個(gè)才應(yīng)該是我們的選擇,但是有些情況下這樣的寫法不能解決的,
            或者說(shuō)解決起來(lái)不好,所以引入命令模式.
            (1)我們須要Client和Receiver同時(shí)開(kāi)發(fā),而且在開(kāi)發(fā)過(guò)程中分別須要不停重購(gòu),改名
            (2)如果我們要求Redo ,Undo等功能
            (3)我們須要命令不按照調(diào)用執(zhí)行,而是按照?qǐng)?zhí)行時(shí)的情況排序,執(zhí)行
            (4)開(kāi)發(fā)后期,我們發(fā)現(xiàn)必須要log哪些方法執(zhí)行了,如何在盡量少更改代碼的情況下實(shí)現(xiàn).并且漸少重復(fù)代碼
            (5)在上邊的情況下,我們的接受者有很多,不止一個(gè)
            解決辦法:
            情況一,我們可以定義一個(gè)接口,讓Receiver實(shí)現(xiàn)這個(gè)接口,Client按照接口調(diào)用。
            情況二,我們可以讓Receiver記住一些狀態(tài),例如執(zhí)行前的自己的狀態(tài),用來(lái)undo,但自己記錄自己的狀態(tài)
             實(shí)現(xiàn)起來(lái)比較混亂,一般都是一個(gè)累記錄另一個(gè)類的狀態(tài).
            情況三,很難實(shí)現(xiàn)
            情況四,,我們須要在每個(gè)Action,前后加上log
            情況五,相對(duì)好實(shí)現(xiàn),但是再加上這個(gè),是否感覺(jué)最終的實(shí)現(xiàn)很混亂呢
            好,我們?cè)賮?lái)看看命令模式,在命令模式中,我們?cè)黾右恍┻^(guò)渡的類,這些類就是上邊的命名接口和命令實(shí)現(xiàn),
            這樣就很好的解決了情況一,情況二。我們?cè)偌尤胍粋€(gè)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        //按照自定義優(yōu)先級(jí),排序取出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的實(shí)現(xiàn)是否很像代理模式呢,Invoker的這種實(shí)現(xiàn)其實(shí)就是一種代理模式。

            2,需求:有個(gè)固定命令組合會(huì)多次被執(zhí)行
               解決:加入合成模式,實(shí)現(xiàn)方法如下,定義一個(gè)宏命令類:

             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
              解決:加入備忘錄模式,一個(gè)簡(jiǎn)單的實(shí)現(xiàn)如下
             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        //恢復(fù)狀態(tài)
            13    }
            14    public void redo(){
            15        lastReceiver.actionOne();
            16        //
            17    }
            18    public record(){
            19        //記錄狀態(tài)
            20    }
            21}
            4,需求:命令很多類似的地方
               解決:使用原型模式,利用clone
               這個(gè)就不寫例子了。
            四,命令模式的使用場(chǎng)合
            1,須要callback的時(shí)候,例如java awt/swing/swt中的Listening的消息方式
            2,須要對(duì)請(qǐng)求排隊(duì)執(zhí)行,命令的發(fā)送者和接受者有不同對(duì)的生命周期,就是命令執(zhí)行的時(shí)候,可能發(fā)出命令的
            Client已經(jīng)不存在了
            3,須要Redo Undo等函數(shù)
            4,須要log每條命令
            5,須要支持transaction,封裝一組數(shù)據(jù)命令的時(shí)候.
            五,最后再次總結(jié)一下命令模式的優(yōu)點(diǎn)和缺點(diǎn):
            優(yōu)點(diǎn):
            降低Client和命令接受者的耦合,是命令請(qǐng)求和命令執(zhí)行的對(duì)象分割
            便于修改和擴(kuò)張
            便于聚合多個(gè)命令
            缺點(diǎn):
            造成出現(xiàn)過(guò)多的具體命令類,太多文件。

            五,一個(gè)比較有意思的例子,來(lái)說(shuō)明命令模式
            Client        :看電視的人
            Invoker     :遙控器
            Command :電信號(hào)
            具體命令 :遙控器上的按鍵對(duì)應(yīng)的不同的電信號(hào)
            Receiver    :電視機(jī)
            最后說(shuō)一句,并不是全部按照模式寫一定就好,應(yīng)該根據(jù)你的需求來(lái)應(yīng)用,或者全部應(yīng)用,或者部分應(yīng)用,或者根本不用。

            posted on 2011-01-09 14:00 大龍 閱讀(390) 評(píng)論(0)  編輯 收藏 引用


            只有注冊(cè)用戶登錄后才能發(fā)表評(píng)論。
            網(wǎng)站導(dǎo)航: 博客園   IT新聞   BlogJava   博問(wèn)   Chat2DB   管理


            欧美精品九九99久久在观看| 久久国产精品无码HDAV| 精品久久久久久国产免费了| 久久国产视屏| 久久精品九九亚洲精品| 国产午夜精品理论片久久| 久久久久久精品无码人妻| 国产成年无码久久久久毛片| 一级女性全黄久久生活片免费 | 色综合合久久天天综合绕视看| 久久嫩草影院免费看夜色| 99久久精品免费看国产一区二区三区| 人人狠狠综合久久亚洲88| 亚洲色大成网站www久久九| 久久精品国产亚洲一区二区三区| 久久久无码一区二区三区| 久久九九久精品国产| 亚洲国产精品人久久| 久久久久亚洲av无码专区喷水| 中文字幕精品久久| 久久久久久国产精品美女 | 国产福利电影一区二区三区久久老子无码午夜伦不 | 国内高清久久久久久| 久久综合久久伊人| 99久久精品免费国产大片| 久久久精品国产sm调教网站 | 久久久久青草线蕉综合超碰| 99久久婷婷国产综合精品草原| 久久精品国产久精国产思思| 久久久久亚洲av成人网人人软件 | 热久久这里只有精品| 久久99毛片免费观看不卡| 久久综合狠狠综合久久| 久久久久亚洲av无码专区| 精品乱码久久久久久久| 狠狠色丁香婷婷久久综合不卡 | 麻豆久久| 国产aⅴ激情无码久久| 久久国产精品一国产精品金尊| 国产精品久久久久久久久鸭 | 久久国产乱子伦精品免费强|