1. 定义
- 将一个请求封装成一个对象,从而让用户使用不同的请求把客户端参数化;对请求排队或记录请求日志,以及支持可撤销的操作。
2. UML类图

- Receiver:接收者角色,命令的真正执行者,任何类都可以成为一个接收者,而在接收者类中封装具体操作逻辑的方法我们则称为行动方法
- Command:命令角色,定义所有命令方法的接口
- ConcreteCommand:具体命令角色,Command的具体实现类,在execute方法中调用接收者角色的相关方法,在接收者和命令执行的具体行为之间加以弱耦合
- Invoker:请求者角色,主要职责是调用命令对象执行具体的请求,相关的方法被称为行动方法
- Client:客户端角色
4. 使用场景
- 当某项操作具备命令语义时,且命令实现存在不确定性,容易变化,那么可以通过命令模式解耦请求与实现,利用抽象命令接口使请求方代码架构稳定,封装接收方实现命令的具体细节
- 语义中具备 “命令”的操作(如命令菜单,shell 命令⋯);
- 请求调用者和请求的接收者需要解耦,使得调用者和接收者不直接交互;
- 需要抽象出等待执行的行为,比如撤销(Undo)操作和恢复(Redo)等操作;
- 需要支持命令宏(即命令组合操作)。
5. 简单实现
- 模拟一个儿童遥控车,遥控器上的前进后退相当于命令,具体实现这个命令的为遥控车
- 首先定义一个遥控车对象(命令实现者),本身拥有前进后退的功能
public class Telecar {
public void forward() {
System.out.println("前进");
}
public void retreat() {
System.out.println("后退");
}
}
public interface ICommand {
void execute();
}
public class ForwardCommand implements ICommand {
private final Telecar telecar;
public ForwardCommand(Telecar telecar) {
this.telecar = telecar;
}
@Override
public void execute() {
telecar.forward();
}
}
public class RetreatCommand implements ICommand {
private final Telecar telecar;
public RetreatCommand(Telecar telecar) {
this.telecar = telecar;
}
@Override
public void execute() {
telecar.retreat();
}
}
public class Buttons {
private ForwardCommand forwardCommand;
private RetreatCommand retreatCommand;
public void setForwardCommand(ForwardCommand forwardCommand) {
this.forwardCommand = forwardCommand;
}
public void setRetreatCommand(RetreatCommand retreatCommand) {
this.retreatCommand = retreatCommand;
}
public void forward() {
forwardCommand.execute();
}
public void retreat() {
retreatCommand.execute();
}
}
public class Client {
public static void main(String[] args) {
Telecar telecar = new Telecar();
Buttons buttons = new Buttons();
buttons.setForwardCommand(new ForwardCommand(telecar));
buttons.setRetreatCommand(new RetreatCommand(telecar));
buttons.forward();
buttons.retreat();
}
}
执行结果:
前进
后退
6. 源码中的使用场景
7. 优缺点
- 优点:
- 降低命令请求与实现的耦合性
- 扩展性好,可以很灵活的增加新接口
- 缺点: