Command 和 Active Object 模式
Command 和 Active Object 模式
Command 模式是封裝了一個沒有任何變量的函數。
public interface Command {public void do(); }簡單的Command
打印機工作流
開啟/關閉繼電器—RelayOnCommand、RelayOffCommand;
開啟/關閉發動機—MotorOnCommand、MotorOffCommand;
開啟/關閉離合器—ClutchOnCommand、ClutchOffCommand;
事務操作
? ? ? ? 另一個Command 模式的常見用法是創建和執行事務操作(Transactions)。當用戶決定增加一個新雇員時,該用戶必須詳細指明成功創建一條雇員記錄所需的所有信息。在使用這些信息前,系統需要驗證這些信息語法和語義上的正確性。Command 對象存儲了還未驗證的數據,實現了實施驗證的方法,并且實現了最后執行事務操作的方法。
? ? ? ? validate() 方法檢查所有數據并確保數據是有意義的。
? ? ? ? execute() 方法用已經驗證過的數據去更新數據庫。
?
Active Object 模式
? ? ? ? Active Object 模式是使用Command 模式的地方之一。這是實現多線程控制的一項古老的技術。
ActiveObjectEngine.java
import java.util.LinkedList;public class ActiveObjectEngine {/*** 命令鏈表.*/private LinkedList<Command> itsCommands = new LinkedList<>();/*** 添加命令.* @param c 命令.*/public void addCommand(Command c) {this.itsCommands.add(c);}/*** 運行.*/public void run() {while (!itsCommands.isEmpty()) {Command c = itsCommands.getFirst();itsCommands.removeFirst();System.out.println("--->Command.execute()");c.execute();}} }Command.java
public interface Command {public void execute();}SleepCommandTest.java
import org.junit.Assert; import org.junit.Test;public class SleepCommandTest {private boolean commandExecuted = false;@Testpublic void testSleep() {Command wakeupCommand = new Command() {@Overridepublic void execute() {commandExecuted = true;System.out.println("WakeUp...");}};ActiveObjectEngine engine = new ActiveObjectEngine();SleepCommand sleepCommand = new SleepCommand(wakeupCommand, engine, 1000);engine.addCommand(sleepCommand);long start = System.currentTimeMillis();engine.run();long stop = System.currentTimeMillis();long sleepTime = (stop - start);Assert.assertTrue("SleepTime " + sleepTime + " expected > 900", sleepTime > 900);Assert.assertTrue("SleepTime " + sleepTime + " expected < 1100", sleepTime < 1100);Assert.assertTrue("Command Executed", commandExecuted);} }SleepCommand.java
public class SleepCommand implements Command {/*** 喚醒命令.*/private Command wakeupCommand = null;/*** 引擎.*/private ActiveObjectEngine engine = null;/*** 休眠時間.*/private long sleepTime = 0l;/*** 開始時間.*/private long startTime = 0l;/*** 是否已開始.*/private boolean started = false;/*** 構造器.*/public SleepCommand(final Command wakeupCommand, final ActiveObjectEngine engine, final long milliseconds) {super();this.wakeupCommand = wakeupCommand;this.engine = engine;this.sleepTime = milliseconds;}/*** 執行.*/@Overridepublic void execute() {long currentTime = System.currentTimeMillis();if (!started) {started = true;startTime = currentTime;engine.addCommand(this);} else if ((currentTime - startTime) < sleepTime) {engine.addCommand(this);} else {engine.addCommand(wakeupCommand);}}}????????和等待一個事件的多線程程序類比。當多線程程序中的一個線程等待一個事件時,它通常使用一些操作系統調用來阻塞自己直到事件發生。這里并沒有阻塞,如果所等待的((currentTime - startTime) < sleepTime) 這個事件沒有發生,它只是把自己放回到ActiveObjectEngine 中。
? ? ? ? 采用該技術的變體去構建多線程系統已經是一個很常見的實踐。這種類型的線程被稱為run-to-completion 任務(RTC),因為每個Command 實例在下一個Command 實例可以運行之前就運行完成了。RTC 意味著Command 實例不會阻塞。
DelayedCommand.java
public class DelayedCommand implements Command {/*** 延遲毫秒數.*/private long itsDelay;/*** 字符.*/private char itsChar;/*** 引擎.*/private static ActiveObjectEngine engine = new ActiveObjectEngine();/*** 是否停用.*/private static boolean stop = false;public static void main(String[] args) {engine.addCommand(new DelayedCommand(100, '1'));engine.addCommand(new DelayedCommand(300, '3'));engine.addCommand(new DelayedCommand(500, '5'));engine.addCommand(new DelayedCommand(700, '7'));Command stopCommand = new Command() {@Overridepublic void execute() {DelayedCommand.stop = true;}};engine.addCommand(new SleepCommand(stopCommand, engine, 2000));engine.run();}/*** 構造器.*/public DelayedCommand(long delay, char c) {super();itsDelay = delay;itsChar = c;}/*** 執行.*/@Overridepublic void execute() {System.out.print(itsChar);if (!stop) {delayAndRepeat();}}private void delayAndRepeat() {engine.addCommand(new SleepCommand(this, engine, itsDelay));} }總結
以上是生活随笔為你收集整理的Command 和 Active Object 模式的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Preserve Whole Objec
- 下一篇: 有效单元测试之可读性