#95 Updated and clarified Command pattern example
This commit is contained in:
		| @@ -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