你的位置:首页 > ASP.net教程

[ASP.net教程]敏捷软件开发(3)


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