命令模式-Command
将一个命令请求封装为一个对象, 这样就可以使用命令来修改目标对象的相关参数了.
本文的例子是, 狗主人(Master) 希望对狗狗发一些命令, 狗来进行响应, 以达到修改"参数"的作用.
比如, 发出让狗狗坐下, 吐舌头 等命令后...狗狗的参数就从站着变为了坐着, 从没伸出舌头变为了吐出舌头.
HandState枚举
public enum HandState { REACH("伸出爪子"), BACK("没伸出爪子"); private String handState; HandState(String handState) { this.handState = handState; } @Override public String toString() { return handState; } }
PostureState枚举
public enum PostureState { SITTING("坐着"), STANDING("站着"); private String posture; PostureState(String posture) { this.posture = posture; } @Override public String toString() { return posture; } }
TongueState枚举
public enum TongueState { SPIT("吐出舌头"), BACK("没伸出舌头"); private String tongueState; TongueState(String tongueState) { this.tongueState = tongueState; } @Override public String toString() { return tongueState; } }
Command接口
命令的抽象定义.
public interface Command { /** * 对dog执行命令 */ void execute(Dog dog); /** * 再来一遍刚刚那次execute(dog) */ void undo(); /** * 撤销刚刚那次execute(dog) */ void redo(); @Override String toString(); }
HandStateCommand类
握手命令
public class HandStateCommand implements Command { private Dog dog; @Override public void execute(Dog dog) { dog.setHandState(HandState.REACH); this.dog = dog; } @Override public void undo() { if (dog != null) { dog.setHandState(HandState.BACK); } } @Override public void redo() { if (dog != null) { dog.setHandState(HandState.REACH); } } @Override public String toString() { return "让狗伸出爪子的命令"; } }
PostureStateCommand类
站立/坐下姿势命令.
public class PostureStateCommand implements Command { private Dog dog; @Override public void execute(Dog dog) { dog.setPostureState(PostureState.SITTING); this.dog = dog; } @Override public void undo() { if (dog != null) { dog.setPostureState(PostureState.STANDING); } } @Override public void redo() { if (dog != null) { dog.setPostureState(PostureState.SITTING); } } @Override public String toString() { return "让狗坐下的命令"; } }
TongueStateCommand类
伸舌头/合上嘴 命令
public class TongueStateCommand implements Command { private Dog dog; @Override public void execute(Dog dog) { dog.setTongueState(TongueState.SPIT); this.dog = dog; } @Override public void undo() { if (dog != null) { dog.setTongueState(TongueState.BACK); } } @Override public void redo() { if (dog != null) { dog.setTongueState(TongueState.SPIT); } } @Override public String toString() { return "让狗吐出舌头的命令"; } }
Dog类
被命令的对象, 根据命令会改变Dog类的状态.
public class Dog { private HandState handState; private PostureState postureState; private TongueState tongueState; { handState = HandState.BACK; postureState = PostureState.STANDING; tongueState = TongueState.BACK; } public void setHandState(HandState handState) { this.handState = handState; } public void setPostureState(PostureState postureState) { this.postureState = postureState; } public void setTongueState(TongueState tongueState) { this.tongueState = tongueState; } @Override public String toString() { return "Dog{" + "handState=" + handState + ", postureState=" + postureState + ", tongueState=" + tongueState + '}'; } public void printStatus() { System.out.println(this); } }
Master类
由Master来施加命令来对Dog进行一些参数上的改变.
import java.util.Deque; import java.util.LinkedList; public class Master { private Deque<Command> undoStack = new LinkedList<>(); private Command redo ; public Master() { } public void sendCommand(Command command, Dog dog) { System.out.printf("主人使用命令:<%s>\n", command); command.execute(dog); redo = command; undoStack.offerLast(command); } public void undoLastCommand() { if (!undoStack.isEmpty()) { Command previousSpell = undoStack.pollLast(); redo = previousSpell; System.out.printf("主人撤回命令:<%s>\n", previousSpell); previousSpell.undo(); } } public void redoLastCommand() { if (redo!=null) { undoStack.offerLast(redo); System.out.printf("再一次执行了命令:<%s>\n", redo); redo.redo(); } } @Override public String toString() { return "狗的主人"; } }
Main
运行程序/ 场景模拟
public class Main { public static void main(String[] args) { Master master = new Master(); Dog dog = new Dog(); dog.printStatus(); //开始命令狗, 站姿坐姿 master.sendCommand(new PostureStateCommand(), dog); dog.printStatus(); // 开始命令狗, 吐舌头 master.sendCommand(new TongueStateCommand(), dog); dog.printStatus(); master.redoLastCommand(); dog.printStatus(); master.undoLastCommand(); dog.printStatus(); master.redoLastCommand(); dog.printStatus(); master.undoLastCommand(); dog.printStatus(); // 开始命令狗, 伸爪子 master.sendCommand(new HandStateCommand(), dog); dog.printStatus(); master.redoLastCommand(); dog.printStatus(); master.undoLastCommand(); dog.printStatus(); } }
运行结果如下: