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;}@Overridepublic 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 {@Overridepublic 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{@Overridepublic 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;}@Overridepublic 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