命令模式(Command Pattern)是一种行为型设计模式,它将请求封装成一个对象,从而允许使用不同的请求、队列或者日志来参数化其他对象。命令模式支持撤销操作,它的核心思想就是将一个请求封装为一个对象,然后通过不同的命令对象来执行请求。
命令模式主要包含以下几个角色:
- Command(抽象命令):定义一个命令的接口,声明执行命令的方法。
- ConcreteCommand(具体命令):实现抽象命令接口,具体定义一个命令。
- Invoker(调用者):要求该命令执行这个请求。
- Receiver(接收者):知道如何实施与执行一个请求相关的操作。
下面是一个简单的命令模式的 Java 示例,该示例模拟一个遥控器,遥控器有四个按键分别对应不同的电器,可以控制电器的开关,以及撤销上一步操作。
代码语言:javascript复制// 命令接口
interface Command {
void execute();
void undo();
}
// 具体命令-打开电灯
class LightOnCommand implements Command {
private Light light;
public LightOnCommand(Light light) {
this.light = light;
}
public void execute() {
light.on();
}
public void undo() {
light.off();
}
}
// 具体命令-关闭电灯
class LightOffCommand implements Command {
private Light light;
public LightOffCommand(Light light) {
this.light = light;
}
public void execute() {
light.off();
}
public void undo() {
light.on();
}
}
// 具体命令-打开电视
class TvOnCommand implements Command {
private Tv tv;
public TvOnCommand(Tv tv) {
this.tv = tv;
}
public void execute() {
tv.on();
}
public void undo() {
tv.off();
}
}
// 具体命令-关闭电视
class TvOffCommand implements Command {
private Tv tv;
public TvOffCommand(Tv tv) {
this.tv = tv;
}
public void execute() {
tv.off();
}
public void undo() {
tv.on();
}
}
// 电灯类
class Light {
public void on() {
System.out.println("电灯已打开");
}
public void off() {
System.out.println("电灯已关闭");
}
}
// 电视类
class Tv {
public void on() {
System.out.println("电视已打开");
}
public void off() {
System.out.println("电视已关闭");
}
}
// 遥控器类
class RemoteControl {
private Command[] onCommands;
private Command[] offCommands;
private Command undoCommand;
public RemoteControl() {
onCommands = new Command[4];
offCommands = new Command[4];
for (int i = 0; i < 4; i ) {
onCommands[i] = () -> {};
offCommands[i] = () -> {};
}
undoCommand = () -> {};
}
public void setCommand(int slot, Command onCommand, Command offCommand) {
onCommands[slot] = onCommand;
offCommands[slot] = offCommand;
}
public void onButtonPressed(int slot) {
onCommands[slot].execute();
undoCommand = onCommands[slot];
}
public void offButtonPressed(int slot) {
offCommands[slot].execute();
undoCommand = offCommands[slot];
}
public void undoButtonPressed() {
undoCommand.undo();
}
}
// 客户端
public class Client {
public static void main(String[] args) {
RemoteControl remoteControl = new RemoteControl();
Light livingRoomLight = new Light();
Light kitchenLight = new Light();
Tv livingRoomTv = new Tv();
LightOnCommand livingRoomLightOnCommand = new LightOnCommand(livingRoomLight);
LightOffCommand livingRoomLightOffCommand = new LightOffCommand(livingRoomLight);
LightOnCommand kitchenLightOnCommand = new LightOnCommand(kitchenLight);
LightOffCommand kitchenLightOffCommand = new LightOffCommand(kitchenLight);
TvOnCommand livingRoomTvOnCommand = new TvOnCommand(livingRoomTv);
TvOffCommand livingRoomTvOffCommand = new TvOffCommand(livingRoomTv);
remoteControl.setCommand(0, livingRoomLightOnCommand, livingRoomLightOffCommand);
remoteControl.setCommand(1, kitchenLightOnCommand, kitchenLightOffCommand);
remoteControl.setCommand(2, livingRoomTvOnCommand, livingRoomTvOffCommand);
remoteControl.onButtonPressed(0);
remoteControl.offButtonPressed(0);
remoteControl.onButtonPressed(1);
remoteControl.undoButtonPressed();
remoteControl.offButtonPressed(1);
remoteControl.onButtonPressed(2);
remoteControl.offButtonPressed(2);
}
}
在上面的示例代码中,遥控器类 RemoteControl
包含了四个按键,分别对应不同的电器。遥控器类中有一个 setCommand
方法,用于设置不同的命令,通过 onButtonPressed
和 offButtonPressed
方法,分别执行开启和关闭操作。同时,遥控器类还有一个 undoButtonPressed
方法,用于撤销上一步操作。
可以看到,命令模式非常适用于需要支持撤销操作的场景。在该示例中,我们可以通过遥控器来开启和关闭不同的电器,并且可以撤销上一步操作。这样做的好处是,我们可以在不知道电器具体实现的情况下,使用遥控器进行控制,而不必关心每个电器的具体实现方式。