#95 Updated and clarified Command pattern example
This commit is contained in:
		| @@ -299,7 +299,7 @@ A programming idiom is a means of expressing a recurring construct in one or mor | |||||||
| ## <a name="command">Command</a> [↑](#list-of-design-patterns) | ## <a name="command">Command</a> [↑](#list-of-design-patterns) | ||||||
| **Intent:** Encapsulate a request as an object, thereby letting you parameterize clients with different requests, queue or log requests, and support undoable operations. | **Intent:** Encapsulate a request as an object, thereby letting you parameterize clients with different requests, queue or log requests, and support undoable operations. | ||||||
|  |  | ||||||
|  |  | ||||||
|  |  | ||||||
| **Applicability:** Use the Command pattern when you want to | **Applicability:** Use the Command pattern when you want to | ||||||
|  |  | ||||||
|   | |||||||
										
											Binary file not shown.
										
									
								
							| Before Width: | Height: | Size: 38 KiB After Width: | Height: | Size: 27 KiB | 
| @@ -3,7 +3,7 @@ | |||||||
|   realizations="true" associations="true" dependencies="false" nesting-relationships="true">   |   realizations="true" associations="true" dependencies="false" nesting-relationships="true">   | ||||||
|   <class id="1" language="java" name="com.iluwatar.command.ShrinkSpell" project="command"  |   <class id="1" language="java" name="com.iluwatar.command.ShrinkSpell" project="command"  | ||||||
|     file="/command/src/main/java/com/iluwatar/command/ShrinkSpell.java" binary="false" corner="BOTTOM_RIGHT">     |     file="/command/src/main/java/com/iluwatar/command/ShrinkSpell.java" binary="false" corner="BOTTOM_RIGHT">     | ||||||
|     <position height="160" width="141" x="-171" y="634"/>     |     <position height="178" width="141" x="-30" y="681"/>     | ||||||
|     <display autosize="true" stereotype="true" package="true" initial-value="false" signature="true"  |     <display autosize="true" stereotype="true" package="true" initial-value="false" signature="true"  | ||||||
|       sort-features="false" accessors="true" visibility="true">       |       sort-features="false" accessors="true" visibility="true">       | ||||||
|       <attributes public="true" package="true" protected="true" private="true" static="true"/>       |       <attributes public="true" package="true" protected="true" private="true" static="true"/>       | ||||||
| @@ -12,7 +12,7 @@ | |||||||
|   </class>   |   </class>   | ||||||
|   <class id="2" language="java" name="com.iluwatar.command.Goblin" project="command"  |   <class id="2" language="java" name="com.iluwatar.command.Goblin" project="command"  | ||||||
|     file="/command/src/main/java/com/iluwatar/command/Goblin.java" binary="false" corner="BOTTOM_RIGHT">     |     file="/command/src/main/java/com/iluwatar/command/Goblin.java" binary="false" corner="BOTTOM_RIGHT">     | ||||||
|     <position height="106" width="138" x="13" y="1069"/>     |     <position height="-1" width="-1" x="129" y="1223"/>     | ||||||
|     <display autosize="true" stereotype="true" package="true" initial-value="false" signature="true"  |     <display autosize="true" stereotype="true" package="true" initial-value="false" signature="true"  | ||||||
|       sort-features="false" accessors="true" visibility="true">       |       sort-features="false" accessors="true" visibility="true">       | ||||||
|       <attributes public="true" package="true" protected="true" private="true" static="true"/>       |       <attributes public="true" package="true" protected="true" private="true" static="true"/>       | ||||||
| @@ -21,7 +21,7 @@ | |||||||
|   </class>   |   </class>   | ||||||
|   <class id="3" language="java" name="com.iluwatar.command.Wizard" project="command"  |   <class id="3" language="java" name="com.iluwatar.command.Wizard" project="command"  | ||||||
|     file="/command/src/main/java/com/iluwatar/command/Wizard.java" binary="false" corner="BOTTOM_RIGHT">     |     file="/command/src/main/java/com/iluwatar/command/Wizard.java" binary="false" corner="BOTTOM_RIGHT">     | ||||||
|     <position height="160" width="212" x="91" y="235"/>     |     <position height="-1" width="-1" x="129" y="362"/>     | ||||||
|     <display autosize="true" stereotype="true" package="true" initial-value="false" signature="true"  |     <display autosize="true" stereotype="true" package="true" initial-value="false" signature="true"  | ||||||
|       sort-features="false" accessors="true" visibility="true">       |       sort-features="false" accessors="true" visibility="true">       | ||||||
|       <attributes public="true" package="true" protected="true" private="true" static="true"/>       |       <attributes public="true" package="true" protected="true" private="true" static="true"/>       | ||||||
| @@ -30,7 +30,7 @@ | |||||||
|   </class>   |   </class>   | ||||||
|   <class id="4" language="java" name="com.iluwatar.command.Command" project="command"  |   <class id="4" language="java" name="com.iluwatar.command.Command" project="command"  | ||||||
|     file="/command/src/main/java/com/iluwatar/command/Command.java" binary="false" corner="BOTTOM_RIGHT">     |     file="/command/src/main/java/com/iluwatar/command/Command.java" binary="false" corner="BOTTOM_RIGHT">     | ||||||
|     <position height="159" width="142" x="9" y="435"/>     |     <position height="-1" width="-1" x="129" y="561"/>     | ||||||
|     <display autosize="true" stereotype="true" package="true" initial-value="false" signature="true"  |     <display autosize="true" stereotype="true" package="true" initial-value="false" signature="true"  | ||||||
|       sort-features="false" accessors="true" visibility="true">       |       sort-features="false" accessors="true" visibility="true">       | ||||||
|       <attributes public="true" package="true" protected="true" private="true" static="true"/>       |       <attributes public="true" package="true" protected="true" private="true" static="true"/>       | ||||||
| @@ -39,66 +39,58 @@ | |||||||
|   </class>   |   </class>   | ||||||
|   <class id="5" language="java" name="com.iluwatar.command.InvisibilitySpell" project="command"  |   <class id="5" language="java" name="com.iluwatar.command.InvisibilitySpell" project="command"  | ||||||
|     file="/command/src/main/java/com/iluwatar/command/InvisibilitySpell.java" binary="false" corner="BOTTOM_RIGHT">     |     file="/command/src/main/java/com/iluwatar/command/InvisibilitySpell.java" binary="false" corner="BOTTOM_RIGHT">     | ||||||
|     <position height="160" width="141" x="10" y="634"/>     |     <position height="160" width="141" x="151" y="681"/>     | ||||||
|     <display autosize="true" stereotype="true" package="true" initial-value="false" signature="true"  |     <display autosize="true" stereotype="true" package="true" initial-value="false" signature="true"  | ||||||
|       sort-features="false" accessors="true" visibility="true">       |       sort-features="false" accessors="true" visibility="true">       | ||||||
|       <attributes public="true" package="true" protected="true" private="true" static="true"/>       |       <attributes public="true" package="true" protected="true" private="true" static="true"/>       | ||||||
|       <operations public="true" package="true" protected="true" private="true" static="true"/>     |       <operations public="true" package="true" protected="true" private="true" static="true"/>     | ||||||
|     </display>   |     </display>   | ||||||
|   </class>   |   </class>   | ||||||
|   <enumeration id="6" language="java" name="com.iluwatar.command.Visibility" project="command"  |   <class id="6" language="java" name="com.iluwatar.command.Target" project="command"  | ||||||
|     file="/command/src/main/java/com/iluwatar/command/Visibility.java" binary="false" corner="BOTTOM_RIGHT">     |  | ||||||
|     <position height="178" width="157" x="191" y="1069"/>     |  | ||||||
|     <display autosize="true" stereotype="true" package="true" initial-value="false" signature="true"  |  | ||||||
|       sort-features="false" accessors="true" visibility="true">       |  | ||||||
|       <attributes public="true" package="true" protected="true" private="true" static="true"/>       |  | ||||||
|       <operations public="true" package="true" protected="true" private="true" static="true"/>     |  | ||||||
|     </display>   |  | ||||||
|   </enumeration>   |  | ||||||
|   <enumeration id="7" language="java" name="com.iluwatar.command.Size" project="command"  |  | ||||||
|     file="/command/src/main/java/com/iluwatar/command/Size.java" binary="false" corner="BOTTOM_RIGHT">     |  | ||||||
|     <position height="196" width="144" x="-171" y="1069"/>     |  | ||||||
|     <display autosize="true" stereotype="true" package="true" initial-value="false" signature="true"  |  | ||||||
|       sort-features="false" accessors="true" visibility="true">       |  | ||||||
|       <attributes public="true" package="true" protected="true" private="true" static="true"/>       |  | ||||||
|       <operations public="true" package="true" protected="true" private="true" static="true"/>     |  | ||||||
|     </display>   |  | ||||||
|   </enumeration>   |  | ||||||
|   <class id="8" language="java" name="com.iluwatar.command.Target" project="command"  |  | ||||||
|     file="/command/src/main/java/com/iluwatar/command/Target.java" binary="false" corner="BOTTOM_RIGHT">     |     file="/command/src/main/java/com/iluwatar/command/Target.java" binary="false" corner="BOTTOM_RIGHT">     | ||||||
|     <position height="195" width="176" x="13" y="834"/>     |     <position height="-1" width="-1" x="129" y="1014"/>     | ||||||
|     <display autosize="true" stereotype="true" package="true" initial-value="false" signature="true"  |     <display autosize="true" stereotype="true" package="true" initial-value="false" signature="true"  | ||||||
|       sort-features="false" accessors="true" visibility="true">       |       sort-features="false" accessors="true" visibility="true">       | ||||||
|       <attributes public="true" package="true" protected="true" private="true" static="true"/>       |       <attributes public="true" package="true" protected="true" private="true" static="true"/>       | ||||||
|       <operations public="true" package="true" protected="true" private="true" static="true"/>     |       <operations public="true" package="true" protected="true" private="true" static="true"/>     | ||||||
|     </display>   |     </display>   | ||||||
|   </class>   |   </class>   | ||||||
|   <association id="9">     |   <association id="7">     | ||||||
|     <end type="SOURCE" refId="1" navigable="false">       |     <end type="SOURCE" refId="3" navigable="false">       | ||||||
|       <attribute id="10" name="target"/>       |       <attribute id="8" name="redoStack">         | ||||||
|       <multiplicity id="11" minimum="0" maximum="1"/>     |         <position height="20" width="67" x="140" y="451"/>       | ||||||
|  |       </attribute>       | ||||||
|  |       <multiplicity id="9" minimum="0" maximum="2147483647">         | ||||||
|  |         <position height="18" width="25" x="221" y="452"/>       | ||||||
|  |       </multiplicity>     | ||||||
|     </end>     |     </end>     | ||||||
|     <end type="TARGET" refId="8" navigable="true"/>     |     <end type="TARGET" refId="4" navigable="true"/>     | ||||||
|     <display labels="true" multiplicity="true"/>   |     <display labels="true" multiplicity="true"/>   | ||||||
|   </association>   |   </association>   | ||||||
|   <generalization id="12">     |   <generalization id="10">     | ||||||
|  |     <end type="SOURCE" refId="2"/>     | ||||||
|  |     <end type="TARGET" refId="6"/>   | ||||||
|  |   </generalization>   | ||||||
|  |   <association id="11">     | ||||||
|  |     <end type="SOURCE" refId="1" navigable="false">       | ||||||
|  |       <attribute id="12" name="target"/>       | ||||||
|  |       <multiplicity id="13" minimum="0" maximum="1"/>     | ||||||
|  |     </end>     | ||||||
|  |     <end type="TARGET" refId="6" navigable="true"/>     | ||||||
|  |     <display labels="true" multiplicity="true"/>   | ||||||
|  |   </association>   | ||||||
|  |   <generalization id="14">     | ||||||
|     <end type="SOURCE" refId="1"/>     |     <end type="SOURCE" refId="1"/>     | ||||||
|     <end type="TARGET" refId="4"/>   |     <end type="TARGET" refId="4"/>   | ||||||
|   </generalization>   |   </generalization>   | ||||||
|   <generalization id="13">     |  | ||||||
|     <bendpoint x="181" y="435"/>     |  | ||||||
|     <bendpoint x="181" y="634"/>     |  | ||||||
|     <end type="SOURCE" refId="3"/>     |  | ||||||
|     <end type="TARGET" refId="8"/>   |  | ||||||
|   </generalization>   |  | ||||||
|   <generalization id="14">     |  | ||||||
|     <end type="SOURCE" refId="2"/>     |  | ||||||
|     <end type="TARGET" refId="8"/>   |  | ||||||
|   </generalization>   |  | ||||||
|   <association id="15">     |   <association id="15">     | ||||||
|     <end type="SOURCE" refId="3" navigable="false">       |     <end type="SOURCE" refId="3" navigable="false">       | ||||||
|       <attribute id="16" name="undoStack"/>       |       <attribute id="16" name="undoStack">         | ||||||
|       <multiplicity id="17" minimum="0" maximum="2147483647"/>     |         <position height="20" width="70" x="-17" y="451"/>       | ||||||
|  |       </attribute>       | ||||||
|  |       <multiplicity id="17" minimum="0" maximum="2147483647">         | ||||||
|  |         <position height="18" width="25" x="60" y="452"/>       | ||||||
|  |       </multiplicity>     | ||||||
|     </end>     |     </end>     | ||||||
|     <end type="TARGET" refId="4" navigable="true"/>     |     <end type="TARGET" refId="4" navigable="true"/>     | ||||||
|     <display labels="true" multiplicity="true"/>   |     <display labels="true" multiplicity="true"/>   | ||||||
| @@ -112,42 +104,9 @@ | |||||||
|       <attribute id="20" name="target"/>       |       <attribute id="20" name="target"/>       | ||||||
|       <multiplicity id="21" minimum="0" maximum="1"/>     |       <multiplicity id="21" minimum="0" maximum="1"/>     | ||||||
|     </end>     |     </end>     | ||||||
|     <end type="TARGET" refId="8" navigable="true"/>     |  | ||||||
|     <display labels="true" multiplicity="true"/>   |  | ||||||
|   </association>   |  | ||||||
|   <association id="22">     |  | ||||||
|     <end type="SOURCE" refId="8" navigable="false">       |  | ||||||
|       <attribute id="23" name="visibility"/>       |  | ||||||
|       <multiplicity id="24" minimum="0" maximum="1"/>     |  | ||||||
|     </end>     |  | ||||||
|     <end type="TARGET" refId="6" navigable="true"/>     |     <end type="TARGET" refId="6" navigable="true"/>     | ||||||
|     <display labels="true" multiplicity="true"/>   |     <display labels="true" multiplicity="true"/>   | ||||||
|   </association>   |   </association>   | ||||||
|   <association id="25">     |  | ||||||
|     <end type="SOURCE" refId="8" navigable="false">       |  | ||||||
|       <attribute id="26" name="size"/>       |  | ||||||
|       <multiplicity id="27" minimum="0" maximum="1"/>     |  | ||||||
|     </end>     |  | ||||||
|     <end type="TARGET" refId="7" navigable="true"/>     |  | ||||||
|     <display labels="true" multiplicity="true"/>   |  | ||||||
|   </association>   |  | ||||||
|   <association id="28">     |  | ||||||
|     <end type="SOURCE" refId="3" navigable="false">       |  | ||||||
|       <attribute id="29" name="redoStack"/>       |  | ||||||
|       <multiplicity id="30" minimum="0" maximum="2147483647"/>     |  | ||||||
|     </end>     |  | ||||||
|     <end type="TARGET" refId="4" navigable="true"/>     |  | ||||||
|     <display labels="true" multiplicity="true"/>   |  | ||||||
|   </association>   |  | ||||||
|   <association id="31">     |  | ||||||
|     <bendpoint x="-162" y="834"/>     |  | ||||||
|     <end type="SOURCE" refId="1" navigable="false">       |  | ||||||
|       <attribute id="32" name="oldSize"/>       |  | ||||||
|       <multiplicity id="33" minimum="0" maximum="1"/>     |  | ||||||
|     </end>     |  | ||||||
|     <end type="TARGET" refId="7" navigable="true"/>     |  | ||||||
|     <display labels="true" multiplicity="true"/>   |  | ||||||
|   </association>   |  | ||||||
|   <classifier-display autosize="true" stereotype="true" package="true" initial-value="false" signature="true"  |   <classifier-display autosize="true" stereotype="true" package="true" initial-value="false" signature="true"  | ||||||
|     sort-features="false" accessors="true" visibility="true">     |     sort-features="false" accessors="true" visibility="true">     | ||||||
|     <attributes public="true" package="true" protected="true" private="true" static="true"/>     |     <attributes public="true" package="true" protected="true" private="true" static="true"/>     | ||||||
|   | |||||||
										
											Binary file not shown.
										
									
								
							| Before Width: | Height: | Size: 66 KiB | 
| @@ -4,7 +4,18 @@ package com.iluwatar.command; | |||||||
|  *  |  *  | ||||||
|  * In Command pattern actions are objects that can be executed and undone.  |  * In Command pattern actions are objects that can be executed and undone.  | ||||||
|  * |  * | ||||||
|  * In this example the commands are the spells cast by the wizard on the goblin. |  * Four terms always associated with the command pattern are command, receiver, invoker and client. A command  | ||||||
|  |  * object (spell) knows about receiver (target) and invokes a method of the receiver. Values for parameters of  | ||||||
|  |  * the receiver method are stored in the command. The receiver then does the work. An invoker object (wizard)  | ||||||
|  |  * knows how to execute a command, and optionally does bookkeeping about the command execution. The invoker  | ||||||
|  |  * does not know anything about a concrete command, it knows only about command interface. Both an invoker object  | ||||||
|  |  * and several command objects are held by a client object (app). The client decides which commands to execute at  | ||||||
|  |  * which points. To execute a command, it passes the command object to the invoker object. | ||||||
|  |  *  | ||||||
|  |  * In other words, in this example the wizard casts spells on the goblin. The wizard keeps track of the previous | ||||||
|  |  * spells cast, so it is easy to undo them. In addition, the wizard keeps track of the spells undone, so they | ||||||
|  |  * can be redone. | ||||||
|  |  *  | ||||||
|  *  |  *  | ||||||
|  */ |  */ | ||||||
| public class App { | public class App { | ||||||
|   | |||||||
| @@ -1,5 +1,10 @@ | |||||||
| package com.iluwatar.command; | package com.iluwatar.command; | ||||||
|  |  | ||||||
|  | /** | ||||||
|  |  *  | ||||||
|  |  * Goblin is the target of the spells | ||||||
|  |  * | ||||||
|  |  */ | ||||||
| public class Goblin extends Target { | public class Goblin extends Target { | ||||||
|  |  | ||||||
| 	public Goblin() { | 	public Goblin() { | ||||||
|   | |||||||
| @@ -1,5 +1,10 @@ | |||||||
| package com.iluwatar.command; | package com.iluwatar.command; | ||||||
|  |  | ||||||
|  | /** | ||||||
|  |  *  | ||||||
|  |  * InvisibilitySpell is a concrete command | ||||||
|  |  * | ||||||
|  |  */ | ||||||
| public class InvisibilitySpell extends Command { | public class InvisibilitySpell extends Command { | ||||||
|  |  | ||||||
| 	private Target target; | 	private Target target; | ||||||
|   | |||||||
| @@ -1,5 +1,10 @@ | |||||||
| package com.iluwatar.command; | package com.iluwatar.command; | ||||||
|  |  | ||||||
|  | /** | ||||||
|  |  *  | ||||||
|  |  * ShrinkSpell is a concrete command | ||||||
|  |  * | ||||||
|  |  */ | ||||||
| public class ShrinkSpell extends Command { | public class ShrinkSpell extends Command { | ||||||
|  |  | ||||||
| 	private Size oldSize; | 	private Size oldSize; | ||||||
|   | |||||||
| @@ -3,14 +3,17 @@ package com.iluwatar.command; | |||||||
| import java.util.Deque; | import java.util.Deque; | ||||||
| import java.util.LinkedList; | import java.util.LinkedList; | ||||||
|  |  | ||||||
| public class Wizard extends Target { | /** | ||||||
|  |  *  | ||||||
|  |  * Wizard is the invoker of the commands | ||||||
|  |  * | ||||||
|  |  */ | ||||||
|  | public class Wizard { | ||||||
|  |  | ||||||
| 	private Deque<Command> undoStack = new LinkedList<>(); | 	private Deque<Command> undoStack = new LinkedList<>(); | ||||||
| 	private Deque<Command> redoStack = new LinkedList<>(); | 	private Deque<Command> redoStack = new LinkedList<>(); | ||||||
|  |  | ||||||
| 	public Wizard() { | 	public Wizard() { | ||||||
| 		setSize(Size.NORMAL); |  | ||||||
| 		setVisibility(Visibility.VISIBLE); |  | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	public void castSpell(Command command, Target target) { | 	public void castSpell(Command command, Target target) { | ||||||
| @@ -41,5 +44,4 @@ public class Wizard extends Target { | |||||||
| 	public String toString() { | 	public String toString() { | ||||||
| 		return "Wizard"; | 		return "Wizard"; | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| } | } | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user