#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) | ||||
| **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 | ||||
|  | ||||
|   | ||||
										
											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">   | ||||
|   <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">     | ||||
|     <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"  | ||||
|       sort-features="false" accessors="true" visibility="true">       | ||||
|       <attributes public="true" package="true" protected="true" private="true" static="true"/>       | ||||
| @@ -12,7 +12,7 @@ | ||||
|   </class>   | ||||
|   <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">     | ||||
|     <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"  | ||||
|       sort-features="false" accessors="true" visibility="true">       | ||||
|       <attributes public="true" package="true" protected="true" private="true" static="true"/>       | ||||
| @@ -21,7 +21,7 @@ | ||||
|   </class>   | ||||
|   <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">     | ||||
|     <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"  | ||||
|       sort-features="false" accessors="true" visibility="true">       | ||||
|       <attributes public="true" package="true" protected="true" private="true" static="true"/>       | ||||
| @@ -30,7 +30,7 @@ | ||||
|   </class>   | ||||
|   <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">     | ||||
|     <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"  | ||||
|       sort-features="false" accessors="true" visibility="true">       | ||||
|       <attributes public="true" package="true" protected="true" private="true" static="true"/>       | ||||
| @@ -39,66 +39,58 @@ | ||||
|   </class>   | ||||
|   <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">     | ||||
|     <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"  | ||||
|       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>   | ||||
|   </class>   | ||||
|   <enumeration id="6" language="java" name="com.iluwatar.command.Visibility" 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"  | ||||
|   <class id="6" language="java" name="com.iluwatar.command.Target" project="command"  | ||||
|     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"  | ||||
|       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>   | ||||
|   </class>   | ||||
|   <association id="9">     | ||||
|     <end type="SOURCE" refId="1" navigable="false">       | ||||
|       <attribute id="10" name="target"/>       | ||||
|       <multiplicity id="11" minimum="0" maximum="1"/>     | ||||
|   <association id="7">     | ||||
|     <end type="SOURCE" refId="3" navigable="false">       | ||||
|       <attribute id="8" name="redoStack">         | ||||
|         <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 type="TARGET" refId="8" navigable="true"/>     | ||||
|     <end type="TARGET" refId="4" navigable="true"/>     | ||||
|     <display labels="true" multiplicity="true"/>   | ||||
|   </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="TARGET" refId="4"/>   | ||||
|   </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">     | ||||
|     <end type="SOURCE" refId="3" navigable="false">       | ||||
|       <attribute id="16" name="undoStack"/>       | ||||
|       <multiplicity id="17" minimum="0" maximum="2147483647"/>     | ||||
|       <attribute id="16" name="undoStack">         | ||||
|         <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 type="TARGET" refId="4" navigable="true"/>     | ||||
|     <display labels="true" multiplicity="true"/>   | ||||
| @@ -112,42 +104,9 @@ | ||||
|       <attribute id="20" name="target"/>       | ||||
|       <multiplicity id="21" minimum="0" maximum="1"/>     | ||||
|     </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"/>     | ||||
|     <display labels="true" multiplicity="true"/>   | ||||
|   </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"  | ||||
|     sort-features="false" accessors="true" visibility="true">     | ||||
|     <attributes public="true" package="true" protected="true" private="true" static="true"/>     | ||||
|   | ||||
										
											Binary file not shown.
										
									
								
							| Before Width: | Height: | Size: 66 KiB | 
| @@ -1,36 +1,47 @@ | ||||
| package com.iluwatar.command; | ||||
|  | ||||
| /** | ||||
|  *  | ||||
|  * 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. | ||||
|  *  | ||||
|  */ | ||||
| public class App { | ||||
|  | ||||
| 	public static void main(String[] args) { | ||||
| 		Wizard wizard = new Wizard(); | ||||
| 		Goblin goblin = new Goblin(); | ||||
|  | ||||
| 		goblin.printStatus(); | ||||
|  | ||||
| 		wizard.castSpell(new ShrinkSpell(), goblin); | ||||
| 		goblin.printStatus(); | ||||
|  | ||||
| 		wizard.castSpell(new InvisibilitySpell(), goblin); | ||||
| 		goblin.printStatus(); | ||||
|  | ||||
| 		wizard.undoLastSpell(); | ||||
| 		goblin.printStatus(); | ||||
|  | ||||
| 		wizard.undoLastSpell(); | ||||
| 		goblin.printStatus(); | ||||
|  | ||||
| 		wizard.redoLastSpell(); | ||||
| 		goblin.printStatus(); | ||||
|  | ||||
| 		wizard.redoLastSpell(); | ||||
| 		goblin.printStatus(); | ||||
| 	} | ||||
| } | ||||
| package com.iluwatar.command; | ||||
|  | ||||
| /** | ||||
|  *  | ||||
|  * In Command pattern actions are objects that can be executed and undone.  | ||||
|  * | ||||
|  * 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 static void main(String[] args) { | ||||
| 		Wizard wizard = new Wizard(); | ||||
| 		Goblin goblin = new Goblin(); | ||||
|  | ||||
| 		goblin.printStatus(); | ||||
|  | ||||
| 		wizard.castSpell(new ShrinkSpell(), goblin); | ||||
| 		goblin.printStatus(); | ||||
|  | ||||
| 		wizard.castSpell(new InvisibilitySpell(), goblin); | ||||
| 		goblin.printStatus(); | ||||
|  | ||||
| 		wizard.undoLastSpell(); | ||||
| 		goblin.printStatus(); | ||||
|  | ||||
| 		wizard.undoLastSpell(); | ||||
| 		goblin.printStatus(); | ||||
|  | ||||
| 		wizard.redoLastSpell(); | ||||
| 		goblin.printStatus(); | ||||
|  | ||||
| 		wizard.redoLastSpell(); | ||||
| 		goblin.printStatus(); | ||||
| 	} | ||||
| } | ||||
|   | ||||
| @@ -1,15 +1,20 @@ | ||||
| package com.iluwatar.command; | ||||
|  | ||||
| public class Goblin extends Target { | ||||
|  | ||||
| 	public Goblin() { | ||||
| 		setSize(Size.NORMAL); | ||||
| 		setVisibility(Visibility.VISIBLE); | ||||
| 	} | ||||
|  | ||||
| 	@Override | ||||
| 	public String toString() { | ||||
| 		return "Goblin"; | ||||
| 	} | ||||
|  | ||||
| } | ||||
| package com.iluwatar.command; | ||||
|  | ||||
| /** | ||||
|  *  | ||||
|  * Goblin is the target of the spells | ||||
|  * | ||||
|  */ | ||||
| public class Goblin extends Target { | ||||
|  | ||||
| 	public Goblin() { | ||||
| 		setSize(Size.NORMAL); | ||||
| 		setVisibility(Visibility.VISIBLE); | ||||
| 	} | ||||
|  | ||||
| 	@Override | ||||
| 	public String toString() { | ||||
| 		return "Goblin"; | ||||
| 	} | ||||
|  | ||||
| } | ||||
|   | ||||
| @@ -1,31 +1,36 @@ | ||||
| package com.iluwatar.command; | ||||
|  | ||||
| public class InvisibilitySpell extends Command { | ||||
|  | ||||
| 	private Target target; | ||||
|  | ||||
| 	@Override | ||||
| 	public void execute(Target target) { | ||||
| 		target.setVisibility(Visibility.INVISIBLE); | ||||
| 		this.target = target; | ||||
| 	} | ||||
|  | ||||
| 	@Override | ||||
| 	public void undo() { | ||||
| 		if (target != null) { | ||||
| 			target.setVisibility(Visibility.VISIBLE); | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	@Override | ||||
| 	public void redo() { | ||||
| 		if (target != null) { | ||||
| 			target.setVisibility(Visibility.INVISIBLE); | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	@Override | ||||
| 	public String toString() { | ||||
| 		return "Invisibility spell"; | ||||
| 	} | ||||
| } | ||||
| package com.iluwatar.command; | ||||
|  | ||||
| /** | ||||
|  *  | ||||
|  * InvisibilitySpell is a concrete command | ||||
|  * | ||||
|  */ | ||||
| public class InvisibilitySpell extends Command { | ||||
|  | ||||
| 	private Target target; | ||||
|  | ||||
| 	@Override | ||||
| 	public void execute(Target target) { | ||||
| 		target.setVisibility(Visibility.INVISIBLE); | ||||
| 		this.target = target; | ||||
| 	} | ||||
|  | ||||
| 	@Override | ||||
| 	public void undo() { | ||||
| 		if (target != null) { | ||||
| 			target.setVisibility(Visibility.VISIBLE); | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	@Override | ||||
| 	public void redo() { | ||||
| 		if (target != null) { | ||||
| 			target.setVisibility(Visibility.INVISIBLE); | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	@Override | ||||
| 	public String toString() { | ||||
| 		return "Invisibility spell"; | ||||
| 	} | ||||
| } | ||||
|   | ||||
| @@ -1,33 +1,38 @@ | ||||
| package com.iluwatar.command; | ||||
|  | ||||
| public class ShrinkSpell extends Command { | ||||
|  | ||||
| 	private Size oldSize; | ||||
| 	private Target target; | ||||
|  | ||||
| 	@Override | ||||
| 	public void execute(Target target) { | ||||
| 		oldSize = target.getSize(); | ||||
| 		target.setSize(Size.SMALL); | ||||
| 		this.target = target; | ||||
| 	} | ||||
|  | ||||
| 	@Override | ||||
| 	public void undo() { | ||||
| 		if (oldSize != null && target != null) { | ||||
| 			Size temp = target.getSize(); | ||||
| 			target.setSize(oldSize); | ||||
| 			oldSize = temp; | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	@Override | ||||
| 	public void redo() { | ||||
| 		undo(); | ||||
| 	} | ||||
|  | ||||
| 	@Override | ||||
| 	public String toString() { | ||||
| 		return "Shrink spell"; | ||||
| 	} | ||||
| } | ||||
| package com.iluwatar.command; | ||||
|  | ||||
| /** | ||||
|  *  | ||||
|  * ShrinkSpell is a concrete command | ||||
|  * | ||||
|  */ | ||||
| public class ShrinkSpell extends Command { | ||||
|  | ||||
| 	private Size oldSize; | ||||
| 	private Target target; | ||||
|  | ||||
| 	@Override | ||||
| 	public void execute(Target target) { | ||||
| 		oldSize = target.getSize(); | ||||
| 		target.setSize(Size.SMALL); | ||||
| 		this.target = target; | ||||
| 	} | ||||
|  | ||||
| 	@Override | ||||
| 	public void undo() { | ||||
| 		if (oldSize != null && target != null) { | ||||
| 			Size temp = target.getSize(); | ||||
| 			target.setSize(oldSize); | ||||
| 			oldSize = temp; | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	@Override | ||||
| 	public void redo() { | ||||
| 		undo(); | ||||
| 	} | ||||
|  | ||||
| 	@Override | ||||
| 	public String toString() { | ||||
| 		return "Shrink spell"; | ||||
| 	} | ||||
| } | ||||
|   | ||||
| @@ -1,45 +1,47 @@ | ||||
| package com.iluwatar.command; | ||||
|  | ||||
| import java.util.Deque; | ||||
| import java.util.LinkedList; | ||||
|  | ||||
| public class Wizard extends Target { | ||||
|  | ||||
| 	private Deque<Command> undoStack = new LinkedList<>(); | ||||
| 	private Deque<Command> redoStack = new LinkedList<>(); | ||||
|  | ||||
| 	public Wizard() { | ||||
| 		setSize(Size.NORMAL); | ||||
| 		setVisibility(Visibility.VISIBLE); | ||||
| 	} | ||||
|  | ||||
| 	public void castSpell(Command command, Target target) { | ||||
| 		System.out.println(this + " casts " + command + " at " + target); | ||||
| 		command.execute(target); | ||||
| 		undoStack.offerLast(command); | ||||
| 	} | ||||
|  | ||||
| 	public void undoLastSpell() { | ||||
| 		if (!undoStack.isEmpty()) { | ||||
| 			Command previousSpell = undoStack.pollLast(); | ||||
| 			redoStack.offerLast(previousSpell); | ||||
| 			System.out.println(this + " undoes " + previousSpell); | ||||
| 			previousSpell.undo(); | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	public void redoLastSpell() { | ||||
| 		if (!redoStack.isEmpty()) { | ||||
| 			Command previousSpell = redoStack.pollLast(); | ||||
| 			undoStack.offerLast(previousSpell); | ||||
| 			System.out.println(this + " redoes " + previousSpell); | ||||
| 			previousSpell.redo(); | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	@Override | ||||
| 	public String toString() { | ||||
| 		return "Wizard"; | ||||
| 	} | ||||
|  | ||||
| } | ||||
| package com.iluwatar.command; | ||||
|  | ||||
| import java.util.Deque; | ||||
| import java.util.LinkedList; | ||||
|  | ||||
| /** | ||||
|  *  | ||||
|  * Wizard is the invoker of the commands | ||||
|  * | ||||
|  */ | ||||
| public class Wizard { | ||||
|  | ||||
| 	private Deque<Command> undoStack = new LinkedList<>(); | ||||
| 	private Deque<Command> redoStack = new LinkedList<>(); | ||||
|  | ||||
| 	public Wizard() { | ||||
| 	} | ||||
|  | ||||
| 	public void castSpell(Command command, Target target) { | ||||
| 		System.out.println(this + " casts " + command + " at " + target); | ||||
| 		command.execute(target); | ||||
| 		undoStack.offerLast(command); | ||||
| 	} | ||||
|  | ||||
| 	public void undoLastSpell() { | ||||
| 		if (!undoStack.isEmpty()) { | ||||
| 			Command previousSpell = undoStack.pollLast(); | ||||
| 			redoStack.offerLast(previousSpell); | ||||
| 			System.out.println(this + " undoes " + previousSpell); | ||||
| 			previousSpell.undo(); | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	public void redoLastSpell() { | ||||
| 		if (!redoStack.isEmpty()) { | ||||
| 			Command previousSpell = redoStack.pollLast(); | ||||
| 			undoStack.offerLast(previousSpell); | ||||
| 			System.out.println(this + " redoes " + previousSpell); | ||||
| 			previousSpell.redo(); | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	@Override | ||||
| 	public String toString() { | ||||
| 		return "Wizard"; | ||||
| 	} | ||||
| } | ||||
|   | ||||
		Reference in New Issue
	
	Block a user