Java命令模式简介及示例
1. 引言
命令模式(Command Pattern)是一种行为设计模式,它将请求封装成一个对象,从而允许你使用不同的请求、队列或者日志请求来参数化其他对象。命令模式也支持撤销操作。
命令模式中的主要角色有:命令接口(Command Interface)、具体命令(Concrete Command)、命令调用者(Command Invoker)和接收者(Receiver)。
本文将通过一个示例来详细介绍Java命令模式的使用。
2. 示例场景
假设我们正在开发一个简单的遥控器应用程序。遥控器上有几个按钮,每个按钮代表一个电器设备,例如电视、音响等。我们需要实现以下功能:
- 每个按钮可以执行不同的操作,例如打开、关闭、调高音量、调低音量等;
- 每个按钮上都有一个撤销按钮,可以撤销上一次的操作。
3. 实现步骤
3.1 命令接口(Command Interface)
我们首先定义一个命令接口,该接口中包含了执行和撤销命令的方法。
// Command Interface
public interface Command {
void execute();
void undo();
}
此处定义了execute()
方法用于执行命令,undo()
方法用于撤销命令。
3.2 具体命令(Concrete Command)
我们为每个按钮创建具体的命令类,每个命令类都实现了命令接口。
// Concrete Command for turning on the TV
public class TurnOnTvCommand implements Command {
private TV tv;
public TurnOnTvCommand(TV tv) {
this.tv = tv;
}
public void execute() {
tv.turnOn();
}
public void undo() {
tv.turnOff();
}
}
// Concrete Command for increasing the volume of the sound system
public class IncreaseVolumeCommand implements Command {
private SoundSystem soundSystem;
public IncreaseVolumeCommand(SoundSystem soundSystem) {
this.soundSystem = soundSystem;
}
public void execute() {
soundSystem.increaseVolume();
}
public void undo() {
soundSystem.decreaseVolume();
}
}
// Concrete Command for turning off the TV
public class TurnOffTvCommand implements Command {
private TV tv;
public TurnOffTvCommand(TV tv) {
this.tv = tv;
}
public void execute() {
tv.turnOff();
}
public void undo() {
tv.turnOn();
}
}
每个具体命令类都有一个接收者对象,用于执行具体的操作。
3.3 接收者(Receiver)
我们为每个电器设备创建一个接收者类,用于实现电器设备的操作。
// Receiver for the TV
public class TV {
public void turnOn() {
System.out.println("TV turned on");
}
public void turnOff() {
System.out.println("TV turned off");
}
}
// Receiver for the Sound System
public class SoundSystem {
public void increaseVolume() {
System.out.println("Volume increased");
}
public void decreaseVolume() {
System.out.println("Volume decreased");
}
}
3.4 命令调用者(Command Invoker)
我们创建一个命令调用者类,用于执行命令和保存命令历史记录。
// Command Invoker
public class RemoteControl {
private Command[] onCommands;
private Command[] offCommands;
private Command undoCommand;
public RemoteControl() {
onCommands = new Command[2];
offCommands = new Command[2];
Command noCommand = new NoCommand();
for (int i = 0; i < 2; i++) {
onCommands[i] = noCommand;
offCommands[i] = noCommand;
}
undoCommand = noCommand;
}
public void setCommand(int slot, Command onCommand, Command offCommand) {
onCommands[slot] = onCommand;
offCommands[slot] = offCommand;
}
public void pressOnButton(int slot) {
onCommands[slot].execute();
undoCommand = onCommands[slot];
}
public void pressOffButton(int slot) {
offCommands[slot].execute();
undoCommand = offCommands[slot];
}
public void pressUndoButton() {
undoCommand.undo();
}
}
3.5 测试代码
我们在main
方法中进行