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