命令模式就是将命令包装成java对象,来保存命令历史记录和恢复上一个状态、重复执行命令,比如我们写代码的撤销(undo)、取消撤销(redo)
通过演示一个妖怪隐身、缩小、恢复原样的过程,来熟悉命令模式
命令抽象类 /** * 命令抽象类,像编写命令一样操作 * 每个命令都可以恢复执行命令之前的状态 * * @author July * @date 2020/10/22 */ public abstract class Command { public abstract void execute(Receiver receiver); public abstract void undo(); public abstract void redo(); @Override public abstract String toString(); } 让妖怪隐身的命令 /** * 隐形咒是一种具体的命令 */ public class InvisibilityCommand extends Command { private Receiver receiver; @Override public void execute(Receiver receiver) { receiver.setVisibility(Visibility.INVISIBLE); this.receiver = receiver; } @Override public void undo() { if (receiver != null) { receiver.setVisibility(Visibility.VISIBLE); } } @Override public void redo() { if (receiver != null) { receiver.setVisibility(Visibility.INVISIBLE); } } @Override public String toString() { return "invisible"; } } 让妖怪变小的命令 public class ShrinkCommand extends Command { private Size oldSize; private Receiver receiver; @Override public void execute(Receiver receiver) { oldSize = receiver.getSize(); receiver.setSize(Size.SMALL); this.receiver = receiver; } @Override public void undo() { if (oldSize != null && receiver != null) { Size temp = receiver.getSize(); receiver.setSize(oldSize); oldSize = temp; } } @Override public void redo() { undo(); } @Override public String toString() { return "small"; } } 命令接收者的抽象类 public abstract class Receiver { private Size size; private Visibility visibility; public Size getSize() { return size; } public void setSize(Size size) { this.size = size; } public Visibility getVisibility() { return visibility; } public void setVisibility(Visibility visibility) { this.visibility = visibility; } @Override public abstract String toString(); /** * Print status */ public void printStatus() { System.out.println("接收者状态:" + String.format("[size=%s] [visibility=%s]", getSize(), getVisibility())); System.out.println(); } } 妖怪 /** * 妖怪,接收变小和隐身的命令 */ public class GoblinReceiver extends Receiver { public GoblinReceiver() { setSize(Size.NORMAL); setVisibility(Visibility.VISIBLE); } @Override public String toString() { return "GoblinReceiver"; } } 控盘者(调用者) /** * 【关键的角色】命令的调用程序 * * @author July * @date 2020/10/22 */ public class Invoker { /** * 用stack记录 */ private Deque<Command> undoStack = new LinkedList<>(); private Deque<Command> redoStack = new LinkedList<>(); public Invoker() { } /** * Cast spell */ public void call(Command command, Receiver receiver) { System.out.println(this + "在" + receiver + " 上执行命令 " + command); command.execute(receiver); undoStack.offerLast(command); } /** * 撤销最后的操作 */ public void undo() { if (!undoStack.isEmpty()) { Command previousSpell = undoStack.pollLast(); redoStack.offerLast(previousSpell); System.out.println(this + " undoes " + previousSpell + " command"); previousSpell.undo(); } } /** * 重做最后的操作(重新执行命令) */ public void redo() { if (!redoStack.isEmpty()) { Command previousSpell = redoStack.pollLast(); undoStack.offerLast(previousSpell); System.out.println(this + " redoes " + previousSpell + " command"); previousSpell.redo(); } } @Override public String toString() { return "Invoker"; } } 测试类 public class App { public static void main(String[] args) { // 实例化一个调用角色 Invoker invoker = new Invoker(); // 命令执行的接收者(目标) GoblinReceiver goblinReceiver = new GoblinReceiver(); // 打印接收者初始状态 goblinReceiver.printStatus(); // 对妖怪执行缩小命令 invoker.call(new ShrinkCommand(), goblinReceiver); goblinReceiver.printStatus(); // 对妖怪执行隐身命令 invoker.call(new InvisibilityCommand(), goblinReceiver); goblinReceiver.printStatus(); // 回退到上一步操作 invoker.undo(); goblinReceiver.printStatus(); // 回退到上一步操作 invoker.undo(); goblinReceiver.printStatus(); // 前进一步 invoker.redo(); goblinReceiver.printStatus(); // 前进一步 invoker.redo(); goblinReceiver.printStatus(); } }最终的执行结果:
接收者状态:[size=normal] [visibility=visible] Invoker在GoblinReceiver 上执行命令 small 接收者状态:[size=small] [visibility=visible] Invoker在GoblinReceiver 上执行命令 invisible 接收者状态:[size=small] [visibility=invisible] Invoker undoes invisible command 接收者状态:[size=small] [visibility=visible] Invoker undoes small command 接收者状态:[size=normal] [visibility=visible] Invoker redoes small command 接收者状态:[size=small] [visibility=visible] Invoker redoes invisible command 接收者状态:[size=small] [visibility=invisible]