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 

  • 相关阅读:
    log4net使用封装,无缝切换 dotnet 和 dotnetcore
    使用 certbot 申请泛域名https证书
    StackExchange.Redis中文使用文档
    在 asp.net core 中使用类似 Application 的服务
    不一样的 SQL Server 日期格式化
    你可能不知道的 docker 命令的奇淫怪巧
    [k8s]dashboard1.8.1搭建( heapster1.5+influxdb+grafana)
    [k8s]k8s 1.9(on the fly搭建) 1.9_cni-flannel部署排错 ipvs模式
    [k8s] kubelet单组件启动静态pod
    [svc]runinit管理多进程
  • 原文地址:https://www.cnblogs.com/deman/p/5553538.html
Copyright © 2011-2022 走看看