命令模式-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(); } }
運行結果如下: