定义
命令模式(Command Pattern)是一种行为型设计模式,它将一个请求封装为一个对象,从而使你可用不同的请求对客户进行参数化;对请求排队或记录请求日志,以及支持可撤销的操作。
以下是命令模式的主要特点和定义:
主要角色
-
Command(抽象命令类) :
- 声明执行操作的接口,通常包含一个
execute
方法用于执行命令。
- 声明执行操作的接口,通常包含一个
-
ConcreteCommand(具体命令类) :
- 实现抽象命令类,将一个接收者对象绑定于一个动作。
- 调用接收者相应的操作,以实现
execute
方法。
-
Receiver(接收者对象) :
- 知道如何实施与执行一个与请求相关的操作。
-
Invoker(调用者) :
- 要求该命令执行这个请求。
业务
假设我们有一个电灯系统,有开灯和关灯的操作。
classDiagram
class Command {
+execute() : void
}
class LightOnCommand {
-Light light
+execute() : void
}
class LightOffCommand {
-Light light
+execute() : void
}
class Light {
+turnOn() : void
+turnOff() : void
}
class RemoteControl {
-Command command
+setCommand(Command) : void
+pressButton() : void
}
Command <|-- LightOnCommand
Command <|-- LightOffCommand
LightOnCommand --> Light
LightOffCommand --> Light
RemoteControl "1" --> "1" Command
一、定义接收者(Receiver)
首先定义电灯类作为接收者:
class Light {
public void turnOn() {
System.out.println("Light is on.");
}
public void turnOff() {
System.out.println("Light is off.");
}
}
二、定义抽象命令(Command)
创建一个命令接口:
interface Command {
void execute();
}
三、定义具体命令(ConcreteCommand)
实现开灯和关灯的具体命令类:
class LightOnCommand implements Command {
private Light light;
public LightOnCommand(Light light) {
this.light = light;
}
@Override
public void execute() {
light.turnOn();
}
}
class LightOffCommand implements Command {
private Light light;
public LightOffCommand(Light light) {
this.light = light;
}
@Override
public void execute() {
light.turnOff();
}
}
四、定义调用者(Invoker)
class RemoteControl {
private Command command;
public void setCommand(Command command) {
this.command = command;
}
public void pressButton() {
command.execute();
}
}
五、使用命令模式
public class CommandPatternExample {
public static void main(String[] args) {
Light light = new Light();
LightOnCommand onCommand = new LightOnCommand(light);
LightOffCommand offCommand = new LightOffCommand(light);
RemoteControl remote = new RemoteControl();
remote.setCommand(onCommand);
remote.pressButton();
remote.setCommand(offCommand);
remote.pressButton();
}
}
在这个例子中,电灯(Light
)是接收者,命令接口(Command
)定义了执行命令的方法,具体命令类(LightOnCommand
和LightOffCommand
)实现了命令接口并调用接收者的相应方法,遥控器(RemoteControl
)是调用者,负责执行命令。通过这种方式,命令模式将请求的发送者(遥控器)和请求的接收者(电灯)解耦,使得可以方便地添加新的命令和调用者,而不需要修改现有的代码。
总结
使用场景
-
需要将请求调用者和请求接收者解耦。
- 例如在图形用户界面中,一个按钮的点击事件可以被封装成一个命令对象,按钮只需要触发命令的执行,而不需要知道具体的操作是由哪个对象来执行。
-
需要支持可撤销的操作。
- 可以将每个操作封装成一个命令对象,记录命令执行前的状态,以便在需要撤销时恢复到之前的状态。
-
需要支持宏命令,即一组命令的组合执行。
- 可以创建一个包含多个命令对象的宏命令对象,依次执行这些命令。
优点
-
降低了系统的耦合度。
- 请求调用者和请求接收者之间没有直接的代码耦合,通过命令对象进行间接的交互。
-
易于实现可撤销的操作。
- 可以方便地记录命令执行前的状态,以便在需要时进行撤销。
-
易于扩展新的命令。
- 只需要实现新的具体命令类,而不需要修改现有的代码。
缺点
- 可能会导致系统中出现过多的具体命令类,增加系统的复杂性。
- 命令的执行可能会依赖于接收者的状态,如果接收者状态发生变化,可能会影响命令的执行结果。