zoukankan      html  css  js  c++  java
  • 敏捷软件开发(3)---COMMAND 模式 & Active Object 模式

    COMMAND 模式

    command模式非常简单,简单到你无法想象的地方。

    public interface Command {
        void execute();
    }

    这就是一个command模式的样子。也许你会觉得,这有点多此一举吗。但是当你使用他的时候,command模式就会闪现光华。

    这样一个场景:经理张三叫leader王二去开发一个项目, 王二就安排李四 去开发这个功能A。 李四何时执行,怎么执行就是他自己的事情了。


     UML图如上所示:
    代码如下:
    public interface CommandInterface {
        void execute();
    }
    public class ContractCommand implements CommandInterface {
        Member member;
    
        public ContractCommand(Member member) {
            this.member = member;
        }
    
        @Override
        public void execute() {
            member.action();
        }
    }
    public class Member {
        public void action()
        {
            TraceLog.i();
        }
    }

    Leader,获取命令,然后执行命令。

    public class Leader {
        CommandInterface commandInterface;
    
    
        public void setCommandInterface(CommandInterface commandInterface) {
            this.commandInterface = commandInterface;
        }
    
        public void executeCommand()
        {
            commandInterface.execute();
        }
    }
    public class Manager {
        public static void main()
        {
            Member m = new Member();
            CommandInterface c = new ContractCommand(m);
            Leader wang2 = new Leader();
    
            wang2.setCommandInterface(c);
            wang2.executeCommand();
        }
    }

    manager创建运行的平台。

    这样命令模式就开启了。

    Active Object

    Active Object 模式

    一开始蛮难理解这个模式的目的,而且GOF的23中经典模式里也没有这个模式。

    /**
     * @author deman.lu
     * @version on 2016-06-02 14:45
     */
    public class ActiveObjectEngine {
        List<CommandInterface> itsCommands = new ArrayList();
    
        /*need to running in main thread, should check with synchronized*/
        public void addCommand(CommandInterface aCommand)
        {
            itsCommands.add(aCommand);
        }
    
        public void run()
        {
            /*should running in background*/
            while (itsCommands.size() > 0)
            {
                CommandInterface c = itsCommands.get(0);
                itsCommands.remove(0);
                c.execute();
            }
        }
    }

    这个就是ActiveObject的engine,2个函数。一个是把一条command添加到表里面。

    另一个是一个循环,处理问题。仔细思考,这就是消费者,和生产者问题的变种。

    but这里没有线程block的地方。先看完全部代码:

    public class SleepCommand implements CommandInterface {
        @Override
        public void execute() {
            Date currentTime = new Date();
            if (!started) {
                started = true;
                this.startTime = currentTime;
                this.engine.addCommand(this);
            } else {
                long elapsedTime = currentTime.getTime() - startTime.getTime();
                if (elapsedTime < SleepTime) {
                    this.engine.addCommand(this);
                } else {
                    this.engine.addCommand(this.wakeupCommand);
                }
            }
        }
    
        private CommandInterface wakeupCommand = null;
        private ActiveObjectEngine engine = null;
        private long SleepTime = 0;
        private Date startTime;
        private boolean started = false;
    
        public SleepCommand(long milliSeconds, ActiveObjectEngine e,
                            CommandInterface wakeupCommand) {
            this.SleepTime = milliSeconds;
            this.engine = e;
            this.wakeupCommand = wakeupCommand;
        }
    
    }
    public class DelayedTyper implements CommandInterface {
        private long itsDelay;
        private char itsChar;
        private static boolean stop = false;
        static String printStr = "";
        private static ActiveObjectEngine engin =
                new ActiveObjectEngine();
    
        static class StopCommand implements CommandInterface
        {
            @Override
            public void execute() {
                DelayedTyper.stop = true;
            }
        }
    
        public static void Main()
        {
            engin.addCommand(new DelayedTyper(100, 'A'));
            engin.addCommand(new DelayedTyper(300, 'B'));
            engin.addCommand(new DelayedTyper(500, 'C'));
            engin.addCommand(new DelayedTyper(700, 'D'));
    
            CommandInterface stopCommand = new StopCommand();
            engin.addCommand(new SleepCommand(2000, engin, stopCommand));
            engin.run();
            TraceLog.i(printStr);
        }
    
        public DelayedTyper(long delay, char c)
        {
            this.itsDelay = delay;
            this.itsChar = c;
        }
    
        @Override
        public void execute()
        {
            printStr +=itsChar;
            if (!stop)
            {
                DelayAndRepeat();
            }
        }
    
        private void DelayAndRepeat()
        {
            engin.addCommand(new SleepCommand(itsDelay, engin, this));
        }
    }

    结果如下:

    ABCDAAABACABAADAABCAAABAADABCAAABAACDB

    当DelayedTyper没有到执行的时间点的时候,启动SleepCommand。

    这个很关键,

                if (elapsedTime < SleepTime) {
                    this.engine.addCommand(this);
                } else {
                    this.engine.addCommand(this.wakeupCommand);
                }

    如果时间没到,就把自己加入到队列最后,等待下次执行。(此处没有用常见的线程block技术)

    时间到了,就把wakeupCommand加入执行队列。

    这里还有个关键是,没有stopcommand,命令会一直循环执行。

    参考:

    《敏捷软件开发》 Robert C. Martin 

  • 相关阅读:
    GTK+ 3.6.2 发布,小的 bug 修复版本
    RunJS 新增 Echo Ajax 测试功能
    Mozilla 发布 Popcorn Maker,在线创作视频
    Sina微博OAuth2框架解密
    Mina状态机State Machine
    Mozilla 发布 Shumway —— 纯JS的SWF解析器
    Code Browser 4.5 发布,代码浏览器
    ROSA 2012 "Enterprise Linux Server" 发布
    ltrace 0.7.0 发布,程序调试工具
    Artifactory 2.6.5 发布,Maven 扩展工具
  • 原文地址:https://www.cnblogs.com/deman/p/5553538.html
Copyright © 2011-2022 走看看