JAVA设计模式命令模式(Command)
引言
在软件开发中,设计模式是经过验证的解决方案,用于解决特定的设计问题或重复出现的问题。这些模式可以提高代码的可读性、可维护性和可扩展性。本文将介绍一种行为型设计模式——命令模式(Command Pattern),并探讨其在Java中的实现和应用。
什么是命令模式?
命令模式是一种行为设计模式,它将请求封装成对象,从而使你可用不同的请求对客户进行参数化;对请求排队或记录请求日志,以及支持可撤销的操作。命令模式的核心思想是将“请求”作为一个对象,将操作请求者与操作执行者解耦。
主要角色
- 命令(Command):声明执行操作的接口。
- 具体命令(Concrete Command):实现了命令接口,定义了具体的执行逻辑。
- 接收者(Receiver):执行命令的具体业务逻辑。
- 调用者(Invoker):负责调用命令对象执行请求。
- 客户端(Client):创建具体命令对象,并设置其接收者。
命令模式的结构
UML类图
+-------------------+ +---------------------+
| Invoker | | ConcreteCommand |
|-------------------| |---------------------|
| - command: Command| | - receiver: Receiver|
|-------------------| |---------------------|
| + setCommand() |<--+ | + execute() |
| + invoke() | | +---------------------+
+-------------------+ |
| +---------------------+
| | Receiver |
+------>|---------------------|
| + action() |
+---------------------+接口与实现
命令接口(Command)
public interface Command {
void execute();
}具体命令(ConcreteCommand)
public class ConcreteCommand implements Command {
private Receiver receiver;
public ConcreteCommand(Receiver receiver) {
this.receiver = receiver;
}
@Override
public void execute() {
receiver.action();
}
}接收者(Receiver)
public class Receiver {
public void action() {
System.out.println("执行具体的操作");
}
}调用者(Invoker)
public class Invoker {
private Command command;
public void setCommand(Command command) {
this.command = command;
}
public void invoke() {
if (command != null) {
command.execute();
}
}
}客户端(Client)
public class Client {
public static void main(String[] args) {
// 创建接收者
Receiver receiver = new Receiver();
// 创建命令对象,关联接收者
Command command = new ConcreteCommand(receiver);
// 创建调用者,设置命令
Invoker invoker = new Invoker();
invoker.setCommand(command);
// 执行命令
invoker.invoke();
}
}命令模式的优点
- 降低系统的耦合度:通过引入中间层(命令对象),降低了请求发送者和接收者之间的耦合。
- 新的命令可以很容易地加入到系统中:只需实现
Command接口即可。 - 可以比较容易地设计一个命令队列:因为每个命令都是一个独立的对象,可以方便地将其放入队列中。
- 支持撤销操作:可以通过保存命令对象的状态来实现撤销功能。
命令模式的缺点
- 可能会导致某些系统有过多的具体命令类:如果系统中有很多命令,会导致类的数量增加。
- 使用命令模式可能会导致系统性能下降:因为每次执行命令都需要创建一个新的命令对象。
应用场景
命令模式适用于以下场景:
- 需要将请求调用者和请求接收者解耦。
- 需要支持撤销操作。
- 需要支持命令的组合操作。
- 需要将请求排队处理。
命令模式是一种非常实用的行为设计模式,它通过将请求封装成对象,使得系统更加灵活和可扩展。通过本文的介绍,希望读者能够理解命令模式的基本概念、结构和应用场景,并能够在实际项目中灵活运用这一模式。
命令模式(Command Pattern)是一种行为设计模式,它将请求封装成对象,从而使你可以用不同的请求、队列或者请求日志参数化其他对象。命令模式也支持可撤销的操作。
实际应用场景
假设我们正在开发一个智能家居系统,用户可以通过手机应用控制家中的各种设备,如灯光、空调和窗帘等。为了实现这些功能,我们可以使用命令模式来封装每个设备的操作。
示例代码
1. 命令接口 (Command Interface)
首先,定义一个命令接口,所有具体的命令类都将实现这个接口。
public interface Command {
void execute();
void undo();
}2. 具体命令类 (Concrete Command Classes)
接下来,为每个设备操作创建具体的命令类。
// 灯光开启命令
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();
}
}3. 接收者类 (Receiver Class)
接收者类是实际执行命令的对象。
public class Light {
public void on() {
System.out.println("Light is ON");
}
public void off() {
System.out.println("Light is OFF");
}
}4. 调用者类 (Invoker Class)
调用者类负责调用命令对象的 execute 方法。
public class RemoteControl {
private Command onCommand;
private Command offCommand;
private Command undoCommand;
public RemoteControl() {
this.undoCommand = new NoCommand(); // 默认的空命令
}
public void setOnCommand(Command onCommand) {
this.onCommand = onCommand;
}
public void setOffCommand(Command offCommand) {
this.offCommand = offCommand;
}
public void onButtonWasPushed() {
onCommand.execute();
undoCommand = onCommand;
}
public void offButtonWasPushed() {
offCommand.execute();
undoCommand = offCommand;
}
public void undoButtonWasPushed() {
if (undoCommand != null) {
undoCommand.undo();
}
}
private static class NoCommand implements Command {
@Override
public void execute() {
// Do nothing
}
@Override
public void undo() {
// Do nothing
}
}
}5. 客户端代码 (Client Code)
最后,客户端代码将创建具体的命令对象,并将其设置到调用者对象中。
public class CommandPatternDemo {
public static void main(String[] args) {
Light livingRoomLight = new Light();
Command livingRoomLightOn = new LightOnCommand(livingRoomLight);
Command livingRoomLightOff = new LightOffCommand(livingRoomLight);
RemoteControl remoteControl = new RemoteControl();
remoteControl.setOnCommand(livingRoomLightOn);
remoteControl.setOffCommand(livingRoomLightOff);
remoteControl.onButtonWasPushed(); // 输出: Light is ON
remoteControl.offButtonWasPushed(); // 输出: Light is OFF
remoteControl.undoButtonWasPushed(); // 输出: Light is ON
}
}客户端代码创建了具体的命令对象,并将其设置到调用者对象中。调用者对象负责调用命令对象的 execute 和 undo 方法,从而实现了对设备的控制。这种设计使得系统的扩展性和灵活性大大增强,同时也支持了命令的撤销操作。命令模式(Command Pattern)是行为设计模式的一种,它将请求封装成对象,从而使你可用不同的请求对客户进行参数化;对请求排队或记录请求日志,以及支持可撤销的操作。这种模式有助于解耦请求的发送者和接收者。
命令模式的基本结构
- Command(命令接口):声明执行操作的接口。
- ConcreteCommand(具体命令类):实现命令接口,定义与接收者相关的绑定操作。
- Receiver(接收者):知道如何实施与执行一个请求相关的操作。任何类都可能作为一个接收者。
- Invoker(调用者):要求该命令执行这个请求。
- Client(客户端):创建一个具体命令对象并设定它的接收者。
示例代码
假设我们有一个简单的家用电器控制系统,可以控制电灯的开关。
1. Command 接口
public interface Command {
void execute();
}2. ConcreteCommand 类
public class LightOnCommand implements Command {
private Light light;
public LightOnCommand(Light light) {
this.light = light;
}
@Override
public void execute() {
light.turnOn();
}
}
public class LightOffCommand implements Command {
private Light light;
public LightOffCommand(Light light) {
this.light = light;
}
@Override
public void execute() {
light.turnOff();
}
}3. Receiver 类
public class Light {
public void turnOn() {
System.out.println("Light is on");
}
public void turnOff() {
System.out.println("Light is off");
}
}4. Invoker 类
public class RemoteControl {
private Command slot;
public void setCommand(Command command) {
slot = command;
}
public void buttonWasPressed() {
slot.execute();
}
}5. Client 类
public class Client {
public static void main(String[] args) {
// 创建接收者
Light light = new Light();
// 创建命令对象
Command lightOn = new LightOnCommand(light);
Command lightOff = new LightOffCommand(light);
// 创建调用者
RemoteControl remoteControl = new RemoteControl();
// 设置命令
remoteControl.setCommand(lightOn);
remoteControl.buttonWasPressed(); // 输出: Light is on
remoteControl.setCommand(lightOff);
remoteControl.buttonWasPressed(); // 输出: Light is off
}
}总结
通过上述示例,可以看到命令模式的主要优点包括:
- 低耦合:发送者和接收者之间没有直接的依赖关系,这使得系统更加灵活。
- 扩展性:可以很容易地增加新的命令,只需要实现
Command接口即可。 - 支持撤销操作:可以在
Command接口中添加undo()方法来实现撤销功能。
命令模式在很多框架和库中都有应用,例如在 GUI 应用中处理用户输入、在游戏开发中处理玩家命令等。
















