命令模式

命令模式UML类图

命令模式UML类图

命令模式java实现

/**
* Enumeration for target size.
*/
public enum Size {

SMALL("small"), NORMAL("normal");

private String title;

Size(String title) {
this.title = title;
}

@Override
public String toString() {
return title;
}
}

/**
* Enumeration for target visibility.
*/
public enum Visibility {

VISIBLE("visible"), INVISIBLE("invisible");

private String title;

Visibility(String title) {
this.title = title;
}

@Override
public String toString() {
return title;
}
}

/**
* Interface for Commands.
*/
public abstract class Command {

public abstract void execute(Target target);

public abstract void undo();

public abstract void redo();

@Override
public abstract String toString();

}

/**
* ShrinkSpell is a concrete command.
收缩法术是一个具体的命令。
*/
public class ShrinkSpell extends Command {

private Size oldSize;
private Target target;

@Override
public void execute(Target target) {
oldSize = target.getSize();
target.setSize(Size.SMALL);
this.target = target;
}

@Override
public void undo() {
if (oldSize != null && target != null) {
var temp = target.getSize();
target.setSize(oldSize);
oldSize = temp;
}
}

@Override
public void redo() {
undo();
}

@Override
public String toString() {
//收缩法术
return "Shrink spell";
}
}

/**
* InvisibilitySpell is a concrete command.
隐身法术是一个具体的命令。
*/
public class InvisibilitySpell extends Command {

private Target target;

@Override
public void execute(Target target) {
target.setVisibility(Visibility.INVISIBLE);
this.target = target;
}

@Override
public void undo() {
if (target != null) {
target.setVisibility(Visibility.VISIBLE);
}
}

@Override
public void redo() {
if (target != null) {
target.setVisibility(Visibility.INVISIBLE);
}
}

@Override
public String toString() {
//隐形法术
return "Invisibility spell";
}
}

/**
* Base class for spell targets.
*/
public abstract class Target {

private static final Logger LOGGER = LoggerFactory.getLogger(Target.class);

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() {
LOGGER.info("{}, [size={}] [visibility={}]", this, getSize(), getVisibility());
}
}

/**
* Goblin is the target of the spells.
地精是法术的目标。
*/
public class Goblin extends Target {

public Goblin() {
setSize(Size.NORMAL);
setVisibility(Visibility.VISIBLE);
}

@Override
public String toString() {
return "Goblin";
}

}

/**
* Wizard is the invoker of the commands.
向导是命令的调用者。
*/
public class Wizard {

private static final Logger LOGGER = LoggerFactory.getLogger(Wizard.class);

private Deque<Command> undoStack = new LinkedList<>();
private Deque<Command> redoStack = new LinkedList<>();

public Wizard() {
// comment to ignore sonar issue: LEVEL critical
}

/**
* Cast spell.
*/
public void castSpell(Command command, Target target) {
LOGGER.info("{} casts {} at {}", this, command, target);
command.execute(target);
undoStack.offerLast(command);
}

/**
* Undo last spell.
*/
public void undoLastSpell() {
if (!undoStack.isEmpty()) {
var previousSpell = undoStack.pollLast();
redoStack.offerLast(previousSpell);
LOGGER.info("{} undoes {}", this, previousSpell);
previousSpell.undo();
}
}

/**
* Redo last spell.
*/
public void redoLastSpell() {
if (!redoStack.isEmpty()) {
var previousSpell = redoStack.pollLast();
undoStack.offerLast(previousSpell);
LOGGER.info("{} redoes {}", this, previousSpell);
previousSpell.redo();
}
}

@Override
public String toString() {
return "Wizard";
}
}

/**
* The Command pattern is a behavioral design pattern in which an object is used to encapsulate all
* information needed to perform an action or trigger an event at a later time. This information
* includes the method name, the object that owns the method and values for the method parameters.
*
* <p>Four terms always associated with the command pattern are command, receiver, invoker and
* client. A command object (spell) knows about the receiver (target) and invokes a method of the
* receiver. Values for parameters of the receiver method are stored in the command. The receiver
* then does the work. An invoker object (wizard) knows how to execute a command, and optionally
* does bookkeeping about the command execution. The invoker does not know anything about a concrete
* command, it knows only about command interface. Both an invoker object and several command
* objects are held by a client object (app). The client decides which commands to execute at which
* points. To execute a command, it passes the command object to the invoker object.
*
* <p>In other words, in this example the wizard casts spells on the goblin. The wizard keeps track
* of the previous spells cast, so it is easy to undo them. In addition, the wizard keeps track of
* the spells undone, so they can be redone.
命令模式是一种行为设计模式,其中一个对象用于封装以后执行动作或触发事件所需的所有信息。该信息包括方法名称,拥有方法的对象和方法参数的值。
<p>始终与命令模式关联的四个术语是命令,接收者,调用者和客户端。命令对象(咒语)了解接收者(目标)并调用该命令的方法
接收器。接收器方法的参数值存储在命令中。接收者然后完成工作。调用程序对象(向导)知道如何执行命令,并且可以选择对命令执行进行簿记。调用者对具体命令一无所知,只知道命令界面。一个调用者对象和几个命令
对象由客户端对象(应用程序)保存。客户端决定在哪些点执行哪些命令。要执行命令,它将命令对象传递给调用者对象。
<p>换句话说,在此示例中,向导在妖精上施放咒语。该向导会跟踪先前施放的咒语,因此很容易撤消它们。另外,向导会跟踪未撤消的咒语,因此可以重做。
*/
public class App {

/**
* Program entry point.
*
* @param args command line args
*/
public static void main(String[] args) {
var wizard = new Wizard();
var goblin = new Goblin();

goblin.printStatus();

wizard.castSpell(new ShrinkSpell(), goblin);
goblin.printStatus();

wizard.castSpell(new InvisibilitySpell(), goblin);
goblin.printStatus();

wizard.undoLastSpell();
goblin.printStatus();

wizard.undoLastSpell();
goblin.printStatus();

wizard.redoLastSpell();
goblin.printStatus();

wizard.redoLastSpell();
goblin.printStatus();
}
}

应用场景

jdk线程池

23种设计模式