您的位置:首页 > 移动开发 > Objective-C

敏捷软件开发(3)---COMMAND 模式 & Active Object 模式

2016-06-03 13:38 603 查看

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
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: