设计模式——命令模式

本文介绍命令模式。

概念

将一个请求封装成为一个对象,从而使我们可用不同的请求对客户进行参数化;对请求排队或者记录请求日志,以及支持可撤销对操作。

结构和工作原理

  • Command:抽象命令类,声明了用于执行请求对execute()等方法,这些方法可以调用请求接收者的相关操作
  • ConcreteCommand:具体命令类,持有接收者,不同的命令的execute方法将会调用接收者的不同方法
  • Invoker:调用者,请求发送者,通过命令对象来请求相关的操作
  • Receiver:接收者,实现各种不同的具体业务逻辑

命令模式将Invoker调用Receiver的不同方法的过程抽象为不同的对象,由原来直接调用的形式,引入了命令对象,从而将Invoker与Receiver解耦,Invoker不必知道Receiver的接口,更不需要知道是否被执行、何时被执行、以及如何被执行。

命令模式的本质是对命令进行封装,将发出命令的责任和执行命令的责任分割开。命令模式使请求本身成为一个对象,这个对象和其他对象一样可以被存储和传递。

优点:

  • 降低系统的耦合度
  • 新命令可以很容易加入到新系统中
  • 可以容易的设计命令队列和宏队列
  • 可以方便的对请求进行undo、redo

缺点:

  • 使用命令模式可能会导致某些系统有过多的具体命令类

使用场景:

  • 系统需要将请求调用者和请求接收者解耦,使得调用者和接收者不直接交互
  • 系统需要在不同的时间指定请求、将请求排队和执行请求
  • 系统需要支持命令的撤销(Undo)操作和恢复(Redo)操作
  • 系统需要将一组操作组合在一起,即支持宏命令

代码示例

@Slf4j
public class Radio {

public void on() {
log.info("Radio- on- radio is on now!");
}

public void off() {
log.info("Radio- off- bye~");
}
}
public interface Command {

void execute();
}
public class TurnOnCommand implements Command {

private Radio radio;

private TurnOnCommand(Radio radio) {
this.radio = radio;
}

public static TurnOnCommand of(Radio radio) {
return new TurnOnCommand(radio);
}

@Override
public void execute() {
radio.on();
}
}
public class TurnOffCommand implements Command {

private Radio radio;

private TurnOffCommand(Radio radio) {
this.radio = radio;
}

public static TurnOffCommand of(Radio radio) {
return new TurnOffCommand(radio);
}

@Override
public void execute() {
radio.off();
}
}
public class Invoker {

private Command turnOnCommand;

private Command turnOffCommand;

public Invoker(Command turnOnCommand, Command turnOffCommand) {
this.turnOnCommand = turnOnCommand;
this.turnOffCommand = turnOffCommand;
}

public void turnOnRadio() {
turnOnCommand.execute();
}

public void turnOffRadio() {
turnOffCommand.execute();
}
}
public class CommandClient {

public static void main(String[] args) {
Radio radio = new Radio();
Invoker invoker = new Invoker(TurnOnCommand.of(radio), TurnOffCommand.of(radio));
invoker.turnOnRadio();
invoker.turnOffRadio();
}
}

参考资料

https://design-patterns.readthedocs.io/zh_CN/latest/behavioral_patterns/command.html#

Author: nopainanymore
Link: http://nopainanymore.me/DesignPattern-Command/
Copyright Notice: All articles in this blog are licensed under CC BY-NC-SA 4.0 unless stating additionally.
wechat