COMMAND mode
Command mode is very simple and simple enough to be a place you can't imagine.
Public Interface Command { void execute ();}
This is what a command pattern looks like. Maybe you'll think it's a little superfluous. But when you use him, the command pattern flashes.
Such a scenario: Manager Zhang San called leader Wang ER to develop a project, Wang ER to arrange John Doe to develop this function A. John Doe when to execute, how to execute is his own thing.
The UML diagram looks like this: The code is as follows:
Public Interface commandinterface { void execute ();}
Public class Implements commandinterface { Member Member; Public Contractcommand (Member Member) { this. Member= Member; } @Override publicvoid execute () { member.action (); }}
Public class Member { publicvoid action () { tracelog.i ();} }
Leader, gets the command, and then executes the command.
Public class Leader { commandinterface commandinterface; Public void setcommandinterface (Commandinterface commandinterface) { this. Commandinterface= commandinterface; } Public void ExecuteCommand () { commandinterface.execute (); }}
Public class Manager { publicstaticvoid main () { new Member (); New Contractcommand (m); New Leader (); Wang2.setcommandinterface (c); Wang2.executecommand (); }}
The manager creates a running platform.
This mode of command is turned on.
Active Object
Active Object Mode
It was difficult to understand the purpose of the model at first, and there was no such pattern in Gof's 23 classic model.
/** * @authorDeman.lu *@versionOn 2016-06-02 14:45*/ Public classActiveobjectengine {List<CommandInterface> itscommands =NewArrayList (); /*need to running on main thread, should check with synchronized*/ Public voidAddCommand (Commandinterface acommand) {itscommands.add (Acommand); } Public voidrun () {/*should running in background*/ while(Itscommands.size () > 0) {Commandinterface C= Itscommands.get (0); Itscommands.remove (0); C.execute (); } }}
This is the engine,2 function of Activeobject. One is to add a command to the table.
The other is a loop that handles the problem. Thinking carefully, this is a variant of the consumer, and producer problem.
But there is no thread where the block is. Read all the code first:
Public classSleepcommandImplementsCommandinterface {@Override Public voidExecute () {Date currenttime=NewDate (); if(!started) {started=true; This. StartTime =currenttime; This. Engine.addcommand ( This); } Else { LongElapsedTime = Currenttime.gettime ()-Starttime.gettime (); if(ElapsedTime <sleeptime) { This. Engine.addcommand ( This); } Else { This. Engine.addcommand ( This. Wakeupcommand); } } } PrivateCommandinterface Wakeupcommand =NULL; PrivateActiveobjectengine engine =NULL; Private LongSleeptime = 0; PrivateDate StartTime; Private Booleanstarted =false; PublicSleepcommand (LongMilliSeconds, Activeobjectengine E, Commandinterface Wakeupcommand) { This. Sleeptime =MilliSeconds; This. engine =e; This. Wakeupcommand =Wakeupcommand; }}
Public classDelayedtyperImplementsCommandinterface {Private LongItsdelay; Private CharItschar; Private Static BooleanStop =false; StaticString printstr = ""; Private StaticActiveobjectengine Engin =NewActiveobjectengine (); Static classStopcommandImplementsCommandinterface {@Override Public voidExecute () {delayedtyper.stop=true; } } Public Static voidMain () {Engin.addcommand (NewDelayedtyper (+, ' A '))); Engin.addcommand (NewDelayedtyper (' B '))); Engin.addcommand (NewDelayedtyper (+, ' C '))); Engin.addcommand (NewDelayedtyper (the ' D ')); Commandinterface Stopcommand=NewStopcommand (); Engin.addcommand (NewSleepcommand (2000, Engin, Stopcommand)); Engin.run (); TRACELOG.I (PRINTSTR); } PublicDelayedtyper (LongDelayCharc) { This. Itsdelay =delay; This. Itschar =C; } @Override Public voidExecute () {printstr+=Itschar; if(!stop) {delayandrepeat (); } } Private voiddelayandrepeat () {Engin.addcommand (NewSleepcommand (Itsdelay, Engin, This)); }}
The results are as follows:
Abcdaaabacabaadaabcaaabaadabcaaabaacdb
When Delayedtyper is not at the point of execution, start Sleepcommand.
This is key,
if (ElapsedTime < sleeptime) { this] engine.addcommand (this); Else { this. Engine.addcommand (this. wakeupcommand); }
If the time is not reached, add yourself to the queue at the end and wait for the next execution. (No common thread block technology is used here.)
When the time is up, add Wakeupcommand to the execution queue.
The key here is that, without Stopcommand, the command will always be executed in a loop.
Reference:
"Agile Software Development" Robert c. Martin
Agile Software Development (3)---COMMAND mode & Active Object mode