command模式很是簡單,簡單到你沒法想象的地方。ide
public interface Command { void execute(); }
這就是一個command模式的樣子。也許你會以爲,這有點畫蛇添足嗎。可是當你使用他的時候,command模式就會閃現光華。函數
這樣一個場景:經理張三叫leader王二去開發一個項目, 王二就安排李四 去開發這個功能A。 李四什麼時候執行,怎麼執行就是他本身的事情了。this
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,獲取命令,而後執行命令。spa
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建立運行的平臺。線程
這樣命令模式就開啓了。code
Active Object 模式blog
一開始蠻難理解這個模式的目的,並且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添加到表裏面。ip
另外一個是一個循環,處理問題。仔細思考,這就是消費者,和生產者問題的變種。開發
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