敏捷软件开发(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

时间: 2024-10-15 14:36:22

敏捷软件开发(3)---COMMAND 模式 & Active Object 模式的相关文章

Java多线程编程模式实战指南(一):Active Object模式--转载

本文由黄文海首次发布在infoq中文站上:http://www.infoq.com/cn/articles/Java-multithreaded-programming-mode-active-object-part1 .转载请注明作者: 黄文海 出处:http://viscent.iteye.com. Active Object模式简介 Active Object模式是一种异步编程模式.它通过对方法的调用与方法的执行进行解耦来提高并发性.若以任务的概念来说,Active Object模式的核心

Java多线程编程模式实战指南一:Active Object模式(下)

Active Object模式的评价与实现考量 Active Object模式通过将方法的调用与执行分离,实现了异步编程.有利于提高并发性,从而提高系统的吞吐率. Active Object模式还有个好处是它可以将任务(MethodRequest)的提交(调用异步方法)和任务的执行策略(Execution Policy)分离.任务的执行策略被封装在Scheduler的实现类之内,因此它对外是不"可见"的,一旦需要变动也不会影响其它代码,降低了系统的耦合性.任务的执行策略可以反映以下一些

java Active Object模式(下)

Active Object模式的评价与实现考量 Active Object模式通过将方法的调用与执行分离,实现了异步编程.有利于提高并发性,从而提高系统的吞吐率. Active Object模式还有个好处是它可以将任务(MethodRequest)的提交(调用异步方法)和任务的执行策略(Execution Policy)分离.任务的执行策略被封装在Scheduler的实现类之内,因此它对外是不“可见”的,一旦需要变动也不会影响其它代码,降低了系统的耦合性.任务的执行策略可以反映以下一些问题: 采

Java多线程编程模式实战指南:Active Object模式(下)

Active Object模式的评价与实现考量 Active Object模式通过将方法的调用与执行分离,实现了异步编程.有利于提高并发性,从而提高系统的吞吐率. Active Object模式还有个好处是它可以将任务(MethodRequest)的提交(调用异步方法)和任务的执行策略(Execution Policy)分离.任务的执行策略被封装在Scheduler的实现类之内,因此它对外是不“可见”的,一旦需要变动也不会影响其它代码,降低了系统的耦合性.任务的执行策略可以反映以下一些问题: 采

多线程设计模式:第六篇 - ThreadLocal和Active Object模式

一,ThreadLocal Java 中的 ThreadLocal 类给多线程编程提供了一种可以让每个线程具有自己独立空间的机制,在这个空间内存储的数据是线程特有的,不对外共享. ThreadLocal 类提供了 set() 和 get() 方法用于设置和获取线程特有数据,且 ThreadLocal 支持泛型,这样可以通过参数来指定要存储数据的类型. 二,Active Object模式 Active Object模式的主要目的是实现方法调用和执行分离到不同的线程中,这样可以提高调用方的响应速度,

敏捷软件开发 – NULL OBJECT模式

考虑以下代码 Employee e = Db.GetEmployee("Bob"); if(e != null && e.IsTimeToPay(today)) { e.Pay(); } 大多数人曾经由于忘记对null进行检查而受挫.该管用手法虽然常见,但却是丑陋且易出错的. 通过让Db.GetEmployee抛出一个异常而不是返回null,可以减少出错的可能性.不过,try/catch块对比null的检查更加丑陋. 可以使用NULL OBJECT模式来解决这些问题.通

敏捷软件开发:原则、模式与实践——第9章 OCP:开放-封闭原则

第9章 OCP:开放-封闭原则 软件实体(类.模块.函数等)应该是可以扩展的,但是不可修改. 9.1 OCP概述 遵循开放-封闭原则设计出的模块具有两个主要特征: (1)对于扩展是开放的(open for extension).这意味着模块的行为是可以扩展的.当应用的需求改变时,我们可以对模块进行扩展,使其具有满足那些改变的新行为. (2)对于修改是封闭的(closed for modification).对模块进行扩展时,不必改动模块的源代码或者二进制代码.模块的二进制可执行版本,无论是可链接

敏捷软件开发(4)--- TEMPLATE METHOD &amp; STRATEGY 模式

1.TEMPLATE METHOD 泛型,也就是这个模式,是可以基于泛型的. 我们往往会有一些算法,比如排序算法.它的算法部分,我可以把它放在一个基类里面,这样具体类型的比较可以放在子类里面. 看如下冒泡排序算法: package com.joyfulmath.agileexample.template.method; /** * @author deman.lu * @version on 2016-06-09 10:04 */ public abstract class BubbleSort

敏捷软件开发 – FACADE模式和MEDIATOR模式

FACADE模式 Db类使得Application类不需要了解System.Data命名空间中的内部细节.它把System.Data的所有通用性和复杂性隐藏在一个非常简单且特定的接口后面. 像Db这样的FACADE类对System.Data的使用施加了许多规约.它知道如何初始化和关闭数据库连接.它知道如何将ProductData的成员变量转换成数据库字段,或反之.它知道如何去构建合适的查询和命令去操纵数据库.它对用户隐藏了所有的复杂性.在Application看来,System.Data是不存在