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


            伊人色综合久久天天| 久久精品www| 无码AV波多野结衣久久| 国产婷婷成人久久Av免费高清 | 久久精品国产WWW456C0M| 无夜精品久久久久久| 日韩精品久久久肉伦网站| 久久国产成人午夜aⅴ影院 | 久久丫精品国产亚洲av不卡 | 久久久久夜夜夜精品国产| 久久午夜综合久久| 91久久精品91久久性色| 一本大道久久东京热无码AV| 精品无码久久久久久午夜| 伊人久久大香线蕉精品不卡 | 性欧美丰满熟妇XXXX性久久久| 国产 亚洲 欧美 另类 久久| 热re99久久6国产精品免费| 婷婷久久精品国产| 99久久综合狠狠综合久久| 久久精品人人做人人爽电影蜜月| 免费精品国产日韩热久久| 久久嫩草影院免费看夜色| 色综合久久中文综合网| 97久久久久人妻精品专区| 99久久国产亚洲综合精品| 色综合久久中文字幕综合网| 国产精品成人99久久久久91gav| 久久国产一区二区| 精品999久久久久久中文字幕| 无码人妻精品一区二区三区久久久| 国产欧美久久久精品影院| 亚洲精品成人网久久久久久| 国产农村妇女毛片精品久久| 日本免费久久久久久久网站| 狠狠色丁香久久综合五月| 国产成人久久精品一区二区三区| 久久久久亚洲AV片无码下载蜜桃 | 国产精品无码久久四虎| 亚洲精品高清久久| 久久99久久成人免费播放|