命令模式
外观
命令模式(Command Pattern)是一种行为设计模式,它将请求或操作封装为对象,从而使你可以参数化客户端(调用者)与接收者(执行者)之间的交互。这种模式的主要目的是解耦调用者与接收者,支持撤销操作、队列请求或记录日志等功能。
概述[编辑 | 编辑源代码]
命令模式的核心思想是将一个请求封装成一个对象,从而使不同的请求、队列或日志请求参数化其他对象。该模式包含以下几个关键角色:
- 命令接口(Command):声明执行操作的接口。
- 具体命令(ConcreteCommand):实现命令接口,绑定一个接收者对象及其动作。
- 接收者(Receiver):知道如何执行与请求相关的操作。
- 调用者(Invoker):存储命令对象并在适当时机调用命令。
- 客户端(Client):创建具体命令对象并设置其接收者。
命令模式的类图可以用以下结构表示:
代码示例[编辑 | 编辑源代码]
以下是一个简单的命令模式实现示例,模拟一个遥控器控制电灯开关的场景:
Java 示例[编辑 | 编辑源代码]
// 命令接口
interface Command {
void execute();
}
// 接收者:电灯
class Light {
public void turnOn() {
System.out.println("Light is ON");
}
public void turnOff() {
System.out.println("Light is OFF");
}
}
// 具体命令:开灯命令
class TurnOnCommand implements Command {
private Light light;
public TurnOnCommand(Light light) {
this.light = light;
}
@Override
public void execute() {
light.turnOn();
}
}
// 具体命令:关灯命令
class TurnOffCommand implements Command {
private Light light;
public TurnOffCommand(Light light) {
this.light = light;
}
@Override
public void execute() {
light.turnOff();
}
}
// 调用者:遥控器
class RemoteControl {
private Command command;
public void setCommand(Command command) {
this.command = command;
}
public void pressButton() {
command.execute();
}
}
// 客户端代码
public class CommandPatternDemo {
public static void main(String[] args) {
Light light = new Light();
Command turnOn = new TurnOnCommand(light);
Command turnOff = new TurnOffCommand(light);
RemoteControl remote = new RemoteControl();
remote.setCommand(turnOn);
remote.pressButton(); // 输出: Light is ON
remote.setCommand(turnOff);
remote.pressButton(); // 输出: Light is OFF
}
}
Python 示例[编辑 | 编辑源代码]
from abc import ABC, abstractmethod
# 命令接口
class Command(ABC):
@abstractmethod
def execute(self):
pass
# 接收者:电灯
class Light:
def turn_on(self):
print("Light is ON")
def turn_off(self):
print("Light is OFF")
# 具体命令:开灯命令
class TurnOnCommand(Command):
def __init__(self, light):
self.light = light
def execute(self):
self.light.turn_on()
# 具体命令:关灯命令
class TurnOffCommand(Command):
def __init__(self, light):
self.light = light
def execute(self):
self.light.turn_off()
# 调用者:遥控器
class RemoteControl:
def __init__(self):
self.command = None
def set_command(self, command):
self.command = command
def press_button(self):
if self.command:
self.command.execute()
# 客户端代码
if __name__ == "__main__":
light = Light()
turn_on = TurnOnCommand(light)
turn_off = TurnOffCommand(light)
remote = RemoteControl()
remote.set_command(turn_on)
remote.press_button() # 输出: Light is ON
remote.set_command(turn_off)
remote.press_button() # 输出: Light is OFF
实际应用场景[编辑 | 编辑源代码]
命令模式在以下场景中特别有用:
1. GUI 按钮和菜单项:每个按钮点击或菜单选择可以绑定到一个命令对象。 2. 事务系统:支持撤销/重做操作,每个操作被封装为命令对象。 3. 任务队列:将请求排队并按顺序执行。 4. 宏命令:组合多个命令成为一个复合命令。
撤销操作示例[编辑 | 编辑源代码]
命令模式可以扩展以支持撤销操作。以下是支持撤销的 Java 实现:
interface Command {
void execute();
void undo();
}
class Light {
private boolean isOn = false;
public void turnOn() {
isOn = true;
System.out.println("Light is ON");
}
public void turnOff() {
isOn = false;
System.out.println("Light is OFF");
}
public boolean isOn() {
return isOn;
}
}
class ToggleCommand implements Command {
private Light light;
public ToggleCommand(Light light) {
this.light = light;
}
@Override
public void execute() {
if (light.isOn()) {
light.turnOff();
} else {
light.turnOn();
}
}
@Override
public void undo() {
if (light.isOn()) {
light.turnOff();
} else {
light.turnOn();
}
}
}
// 使用示例
public class UndoDemo {
public static void main(String[] args) {
Light light = new Light();
Command toggle = new ToggleCommand(light);
RemoteControl remote = new RemoteControl();
remote.setCommand(toggle);
remote.pressButton(); // 开灯
remote.pressButton(); // 关灯
((ToggleCommand)toggle).undo(); // 撤销最后一次操作(重新开灯)
}
}
优缺点[编辑 | 编辑源代码]
优点[编辑 | 编辑源代码]
- 解耦调用者与接收者。
- 支持撤销/重做操作。
- 可以将命令组合成复合命令(宏命令)。
- 新的命令可以很容易地添加到系统中。
缺点[编辑 | 编辑源代码]
- 可能会导致系统中出现大量的具体命令类。
- 增加了系统的复杂性。
与其他模式的关系[编辑 | 编辑源代码]
- 责任链模式:可以将多个命令对象链接起来。
- 备忘录模式:可用于实现命令的撤销操作。
- 组合模式:可用于实现宏命令。
- 策略模式:命令模式与策略模式都涉及封装行为,但命令模式侧重于动作的执行和撤销,而策略模式侧重于算法的替换。
总结[编辑 | 编辑源代码]
命令模式是一种强大的行为设计模式,特别适用于需要将操作请求与执行解耦的场景。通过将请求封装为对象,我们可以轻松实现撤销、重做、队列和日志等功能。虽然它可能增加一些类的数量,但其灵活性和可扩展性使其成为许多软件系统中的重要模式。