Last active
August 29, 2015 14:27
-
-
Save exallium/cb9abf99de69d365b87f to your computer and use it in GitHub Desktop.
UndoCommand Pattern
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| public enum Action { | |
| ACTION1, ACTION2 | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| /** | |
| * Undoable command. T is a status of some sort. | |
| * A command should know everything it needs to to perform an execute or an undo. | |
| */ | |
| public interface Command<T> { | |
| T execute(); | |
| T undo(); | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| public class Command1 implements Command<Boolean> { | |
| @Override | |
| Boolean execute() { | |
| System.out.println("Ex Comm 1"); | |
| return true; | |
| } | |
| @Override | |
| Boolean undo() { | |
| System.out.println("Undo Comm 1"); | |
| return false; | |
| } | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| public class Command2 implements Command<Boolean> { | |
| @Override | |
| Boolean execute() { | |
| System.out.println("Ex Comm 2"); | |
| return true; | |
| } | |
| @Override | |
| Boolean undo() { | |
| System.out.println("Undo Comm 2"); | |
| return false; | |
| } | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| /** | |
| * Builds Commands given a subset of actions from an enum. | |
| */ | |
| public interface CommandFactory<T, E extends Enum<E>> { | |
| Command<T> createCommand(E action); | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| public class CommandFactory<Boolean, Actions> { | |
| @Override | |
| Command<T> createCommand(E action) { | |
| switch (action) { | |
| case ACTION1: | |
| return new Command1(); | |
| case ACTION2: | |
| return new Command2(); | |
| } | |
| } | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| /** | |
| * An Invoker controls a stream of commands. | |
| * execute will perform a new action | |
| * undo will undo the most recent action | |
| */ | |
| public interface Invoker<T, E extends Enum<E>> { | |
| T execute(@NotNull E action); | |
| @Nullable | |
| T undo(); | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| public class Main { | |
| public static void main(String [] args) { | |
| // You could also inject Invoker via a DI framework ;) | |
| // You can keep different invokers separate via a naming scheme. | |
| final CommandFactory factory = new ExampleFactory(); | |
| final Invoker invoker = new SimpleInvoker(commandFactory); | |
| invoker.execute(Action.ACTION1); | |
| invoker.execute(Action.ACTION2); | |
| invoker.undo(); | |
| invoker.undo(); | |
| } | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| /** | |
| * This is the default invoker implementation | |
| */ | |
| public class SimpleInvoker<T, E extends Enum<E>> implements Invoker<T, E> { | |
| private final Stack<Command<T>> stack = new Stack<>(); | |
| private final CommandFactory<T, E> commandFactory; | |
| public SimpleInvoker(CommandFactory<T, E> commandFactory) { | |
| this.commandFactory = commandFactory; | |
| } | |
| @Override | |
| public T execute(@NotNull final E action) { | |
| stack.push(commandFactory.createCommand(action)); | |
| return action.execute(); | |
| } | |
| @Override | |
| @Nullable | |
| public T undo() { | |
| return stack.isEmpty() ? null : stack.pop().undo(); | |
| } | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment