本文目录导读:

我来为你提供命令模式的详细案例,包含多个实用场景。
智能家居控制系统
基础类结构
// 1. 命令接口
public interface Command {
void execute();
void undo();
}
// 2. 接收者(Receiver)- 各种设备
public class Light {
private boolean isOn = false;
public void on() {
isOn = true;
System.out.println("电灯已打开");
}
public void off() {
isOn = false;
System.out.println("电灯已关闭");
}
}
public class TV {
private int channel = 1;
public void turnOn() {
System.out.println("电视已打开,当前频道:" + channel);
}
public void turnOff() {
System.out.println("电视已关闭");
}
}
具体命令实现
// 3. 具体命令类
public class LightOnCommand implements Command {
private Light light;
public LightOnCommand(Light light) {
this.light = light;
}
@Override
public void execute() {
light.on();
}
@Override
public void undo() {
light.off();
}
}
public class LightOffCommand implements Command {
private Light light;
public LightOffCommand(Light light) {
this.light = light;
}
@Override
public void execute() {
light.off();
}
@Override
public void undo() {
light.on();
}
}
// 4. 调用者(Invoker)- 遥控器
public class RemoteControl {
private Command[] onCommands;
private Command[] offCommands;
private Command undoCommand;
public RemoteControl() {
onCommands = new Command[7];
offCommands = new Command[7];
// 初始化空命令
for (int i = 0; i < 7; i++) {
onCommands[i] = new NoCommand();
offCommands[i] = new NoCommand();
}
undoCommand = new 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();
}
}
带宏命令的高级应用
// 5. 宏命令 - 一键启动家庭影院
public class MacroCommand implements Command {
private Command[] commands;
public MacroCommand(Command[] commands) {
this.commands = commands;
}
@Override
public void execute() {
for (Command command : commands) {
command.execute();
}
}
@Override
public void undo() {
// 反向撤销
for (int i = commands.length - 1; i >= 0; i--) {
commands[i].undo();
}
}
}
// 使用示例
public class HomeTheaterTest {
public static void main(String[] args) {
// 创建接收者
Light light = new Light();
TV tv = new TV();
Stereo stereo = new Stereo();
// 创建命令
Command lightOn = new LightOnCommand(light);
Command tvOn = new TVOnCommand(tv);
Command stereoOn = new StereoOnCommand(stereo);
// 创建宏命令
Command[] partyOn = {lightOn, tvOn, stereoOn};
MacroCommand partyMacro = new MacroCommand(partyOn);
// 设置到遥控器
RemoteControl remote = new RemoteControl();
remote.setCommand(0, partyMacro, new NoCommand());
// 一键启动
remote.pressOnButton(0);
}
}
任务队列与日志系统
// 6. 命令队列实现
public class CommandQueue {
private Queue<Command> queue = new LinkedList<>();
public void addCommand(Command command) {
queue.offer(command);
System.out.println("命令已添加到队列");
}
public void processAll() {
while (!queue.isEmpty()) {
Command command = queue.poll();
command.execute();
}
}
public void undoAll() {
Stack<Command> commandStack = new Stack<>();
// 记录已执行的命令便于撤销
while (!queue.isEmpty()) {
Command command = queue.poll();
command.execute();
commandStack.push(command);
}
// 撤销所有命令
while (!commandStack.isEmpty()) {
commandStack.pop().undo();
}
}
}
// 7. 带日志的命令(用于系统恢复)
public class LoggedCommand implements Command {
private Command command;
private String logMessage;
public LoggedCommand(Command command, String logMessage) {
this.command = command;
this.logMessage = logMessage;
}
@Override
public void execute() {
command.execute();
logCommand();
}
@Override
public void undo() {
command.undo();
logCommand("UNDO: " + logMessage);
}
private void logCommand() {
System.out.println("日志记录: " + logMessage);
}
private void logCommand(String message) {
System.out.println("日志记录: " + message);
}
}
使用示例 - 完整场景
public class CommandPatternDemo {
public static void main(String[] args) {
System.out.println("=== 智能家居控制系统 ===");
// 创建接收者
Light livingRoomLight = new Light();
Light kitchenLight = new Light();
TV livingRoomTV = new TV();
// 创建命令
Command livingRoomLightOn = new LightOnCommand(livingRoomLight);
Command livingRoomLightOff = new LightOffCommand(livingRoomLight);
Command kitchenLightOn = new LightOnCommand(kitchenLight);
Command kitchenLightOff = new LightOffCommand(kitchenLight);
Command tvOn = new TVOnCommand(livingRoomTV);
Command tvOff = new TVOffCommand(livingRoomTV);
// 设置遥控器
RemoteControl remote = new RemoteControl();
remote.setCommand(0, livingRoomLightOn, livingRoomLightOff);
remote.setCommand(1, kitchenLightOn, kitchenLightOff);
remote.setCommand(2, tvOn, tvOff);
// 操作
System.out.println("\n--- 操作客厅灯 ---");
remote.pressOnButton(0);
remote.pressOffButton(0);
remote.pressUndoButton(); // 撤销关闭,重新开启
System.out.println("\n--- 操作电视 ---");
remote.pressOnButton(2);
remote.pressOffButton(2);
// 使用命令队列
System.out.println("\n--- 命令队列处理 ---");
CommandQueue queue = new CommandQueue();
queue.addCommand(new LoggedCommand(livingRoomLightOn, "打开客厅灯"));
queue.addCommand(new LoggedCommand(tvOn, "打开电视"));
queue.addCommand(new LoggedCommand(kitchenLightOn, "打开厨房灯"));
queue.processAll();
}
}
命令模式的优势
| 优势 | 说明 | 示例 |
|---|---|---|
| 解耦 | 请求者和执行者完全解耦 | 遥控器不知道灯的具体实现 |
| 可扩展 | 容易添加新命令 | 新设备只需实现Command接口 |
| 可撤销 | 支持撤销和重做 | undo()方法实现 |
| 队列化 | 命令可以排队执行 | 宏命令、任务队列 |
| 日志化 | 支持记录所有操作 | 系统恢复功能 |
应用场景总结
- GUI按钮:每个按钮对应一个命令
- 数据库事务:提交和回滚操作
- 网络请求:请求的队列化和重试
- 文本编辑器:撤销/重做功能
- 游戏开发:玩家操作记录和回放
命令模式通过将请求封装为对象,实现了请求的发送者和接收者之间的完全解耦,使系统更加灵活和可扩展。