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

