命令模式-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 undoStack = new LinkedList<>();
private Command redo ;
public Master() {
}
public void sendCommand(Command command, Dog dog) {
System.out.printf("主人使用命令:\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("主人撤回命令:\n", previousSpell);
previousSpell.undo();
}
}
public void redoLastCommand() {
if (redo!=null) {
undoStack.offerLast(redo);
System.out.printf("再一次执行了命令:\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();
}
}
运行结果如下: