概述
- 命令模式可以将请求发送者和接收者完全解耦,发送者与接收者之间没有直接引用关系,发送请求的对象只需要知道如何发送请求,而不必知道如何完成请求。
- 定义:将一个请求封装为一个对象,从而让我们可用不同的请求对客户进行参数化;对请求排队或者记录请求日志,以及支持可撤销的操作。
- 也叫为动作(Action)模式或事务(Transaction)模式。
- 命令模式是一种对象行为型模式。
- 学习难度:★★★☆☆
- 使用频率:★★★★☆
优缺点
- 优点
- 类间解耦:调用者和接受者没有依赖,命令角色的execute()来处理具体的调用
- 可扩展:Command子类,具体命令角色非常容易扩展
- 缺点
类图
组成角色
- 接受者角色(Receiver)
- 命令角色(Command)
- 具体命令角色(ConcreteCommand)
- 调用者角色(Invoker)
Code Example
接受者角色(Receiver)
public class Receiver {
public void turnOn() {
System.out.println("灯开了!");
}
public void turnOff() {
System.out.println("灯关了!");
}
}
命令角色(Command)
public interface Command {
public void execute();
}
具体命令角色(ConcreteCommand)
- 请求命令对象化,就是指该角色
- 具体命令角色拥有接受者角色,方便命令对象调用接受者角色执行命令
public class TurnOffCommand implements Command {
private Receiver receiver;
public TurnOffCommand(Receiver receiver) {
this.receiver = receiver;
}
public void execute() {
receiver.turnOff();
}
}
public class TurnOnCommand implements Command {
private Receiver receiver;
public TurnOnCommand(Receiver receiver) {
this.receiver = receiver;
}
public void execute() {
receiver.turnOn();
}
}
调用者角色(Invoker)
- 接受到命令,并调用具体的命令,有种调度的作用
- 调用者角色拥有所有的命令对象
public class Invoker {
private Command turnOffCommand;
private Command turnOnCommand;
public Command getTurnOffCommand() {
return turnOffCommand;
}
public void setTurnOffCommand(Command turnOffCommand) {
this.turnOffCommand = turnOffCommand;
}
public Command getTurnOnCommand() {
return turnOnCommand;
}
public void setTurnOnCommand(Command turnOnCommand) {
this.turnOnCommand = turnOnCommand;
}
public void turnUp() {
turnOnCommand.execute();
}
public void turnDown() {
turnOffCommand.execute();
}
}
客户端
public class Client {
public static void main(String[] args) {
Receiver receiver = new Receiver();
Command turnOn = new TurnOnCommand(receiver);
Command trunOff = new TurnOffCommand(receiver);
Invoker invoker = new Invoker();
invoker.setTurnOnCommand(turnOn);
invoker.setTurnOffCommand(trunOff);
Scanner scanner = new Scanner(System.in);
String input = scanner.next();
try {
if ("ON".equals(input)) {
invoker.turnUp();
} else if ("OFF".equals(input)) {
invoker.turnDown();
} else {
System.out.println("Argument \"ON\" or \"OFF\" is required.");
}
} catch (Exception e) {
System.out.println("Arguments required.");
}
}
}