命令模式是一种行为设计模式,它将请求封装为对象,从而允许我们用不同的请求、队列和日志请求等参数化其他对象。命令模式也可以支持可撤销的操作。
结构
- 命令接口(Command): 定义了执行请求的方法。
public interface Command {
void execute();
}
- 具体命令类(Concrete Command): 实现了命令接口,具体定义了如何执行请求。
public class LightOnCommand implements Command {
private Light light;
public LightOnCommand(Light light) {
this.light = light;
}
public void execute() {
light.turnOn();
}
}
- 接收者类(Receiver): 实际执行请求的对象。
public class Light {
public void turnOn() {
System.out.println("Light is ON");
}
public void turnOff() {
System.out.println("Light is OFF");
}
}
- 调用者类(Invoker): 负责调用命令对象执行请求。
public class RemoteControl {
private Command command;
public void setCommand(Command command) {
this.command = command;
}
public void pressButton() {
command.execute();
}
}
优点和缺点
优点:
- 松耦合: 将请求发送者和接收者解耦,请求发送者不需要知道接收者的具体实现,降低了两者之间的耦合度。
- 可扩展性: 可以方便地新增命令类和接收者类,不影响已有的代码。
- 可撤销的操作: 命令模式支持可撤销的操作,通过保存历史命令,可以实现撤销和重做操作。
- 支持队列操作: 可以将命令对象排队,从而支持对请求的排队和记录。
缺点:
- 类过多: 引入了很多具体命令类和接收者类,可能导致类的数量增多。
- 理解和使用较复杂: 对于简单的场景,命令模式可能会显得过于复杂。
示例
以下是一个简单的命令模式的示例,模拟了一个遥控器控制电灯的操作。
// 命令接口
public interface Command {
void execute();
}
// 具体命令类 - 开灯命令
public class LightOnCommand implements Command {
private Light light;
public LightOnCommand(Light light) {
this.light = light;
}
public void execute() {
light.turnOn();
}
}
// 接收者类 - 电灯
public class Light {
public void turnOn() {
System.out.println("Light is ON");
}
public void turnOff() {
System.out.println("Light is OFF");
}
}
// 调用者类 - 遥控器
public class RemoteControl {
private Command command;
public void setCommand(Command command) {
this.command = command;
}
public void pressButton() {
command.execute();
}
}
// 客户端代码
public class Main {
public static void main(String[] args) {
Light light = new Light();
Command lightOnCommand = new LightOnCommand(light);
RemoteControl remoteControl = new RemoteControl();
remoteControl.setCommand(lightOnCommand);
remoteControl.pressButton(); // 输出:Light is ON
}
}
在这个示例中,Command 是命令接口,LightOnCommand 是具体的开灯命令类,Light 是接收者类,负责实际执行命令。RemoteControl 是调用者类,通过设置不同的命令对象,可以控制不同的操作。当遥控器按下按钮时,会执行相应的命令,从而控制电灯的开关。