### Java 23种设计模式之18命令模式详解
#### 模式介绍
命令模式是一种行为设计模式,它把请求封装成一个对象,从而让我们可以用不同的请求对客户端进行参数化;对请求排队或者记录请求日志,以及支持可撤销的操作。
#### 模式动机
在软件开发过程中,经常会遇到需要向某个对象发送请求的情况,但在这个过程中往往不知道请求的接收者是谁,也不知道具体执行什么操作。在这种情况下,如果能够设计出一种机制,使得请求发送者与请求接收者之间消除耦合,就能够使对象之间的调用关系变得更加灵活。这正是命令模式的主要动机。
#### 模式定义
命令模式(Command Pattern)是一种将请求封装为一个对象,以便使用不同的请求来参数化客户端、队列或日志请求,以及支持可撤销的操作的行为设计模式。在命令模式中,发送者和接收者之间的耦合被解除,发送请求的对象仅需知道如何发送请求而无需关心如何处理请求。
#### 模式结构
命令模式主要涉及以下几种角色:
1. **Command**(抽象命令类):声明了一个执行操作的接口。
2. **ConcreteCommand**(具体命令类):实现了抽象命令接口,拥有接收者对象,并通过调用接收者的功能来完成命令。
3. **Invoker**(调用者):负责调用命令对象中的方法。
4. **Receiver**(接收者):包含了具体的操作逻辑,即实际执行命令的对象。
5. **Client**(客户类):创建具体命令对象并设置其接收者。
#### 模式实例解析
**示例:电视机遥控器**
假设有一个简单的电视机遥控器,它可以控制电视机的开关和频道切换。这个例子很好地说明了命令模式的应用场景。
- **电视机**:接收者(Receiver),执行具体的命令如“打开”、“关闭”或“切换频道”。
- **遥控器**:调用者(Invoker),用户可以通过按下遥控器上的按钮来触发不同的命令。
- **命令接口**:定义了一个执行命令的方法。
- **具体命令类**:实现命令接口,每个具体命令类都与电视机的一个具体操作相对应,例如`OpenCommand`、`CloseCommand`和`ChannelSwitchCommand`。
##### 抽象命令类(Command)
```java
public abstract class Command {
public abstract void execute();
}
```
##### 调用者(Invoker)
```java
public class RemoteControl {
private Command command;
public RemoteControl(Command command) {
this.command = command;
}
public void setCommand(Command command) {
this.command = command;
}
public void pressButton() {
command.execute();
}
}
```
##### 具体命令类(ConcreteCommand)
```java
public class OpenCommand implements Command {
private Receiver receiver;
public OpenCommand(Receiver receiver) {
this.receiver = receiver;
}
@Override
public void execute() {
receiver.open();
}
}
public class CloseCommand implements Command {
private Receiver receiver;
public CloseCommand(Receiver receiver) {
this.receiver = receiver;
}
@Override
public void execute() {
receiver.close();
}
}
public class ChannelSwitchCommand implements Command {
private Receiver receiver;
private int channel;
public ChannelSwitchCommand(Receiver receiver, int channel) {
this.receiver = receiver;
this.channel = channel;
}
@Override
public void execute() {
receiver.switchChannel(channel);
}
}
```
##### 接收者(Receiver)
```java
public class Receiver {
public void open() {
System.out.println("电视机已打开");
}
public void close() {
System.out.println("电视机已关闭");
}
public void switchChannel(int channel) {
System.out.println("切换到频道 " + channel);
}
}
```
#### 模式效果与应用
命令模式提供了一种解耦的方式,让请求的发送者和接收者分离。这种方式有助于降低系统的耦合度,并提高灵活性。此外,命令模式还支持命令的日志记录、命令队列和命令撤销等功能。
1. **降低耦合度**:通过命令模式,调用者无需知道命令是如何被接收以及操作是如何被执行的。
2. **增加新的命令容易**:可以通过添加新的具体命令类来扩展应用程序的功能。
3. **支持撤销操作**:由于命令可以被看作是一个对象,因此可以很容易地将命令对象存储起来,用于实现撤销和重做功能。
#### 总结
命令模式是一种非常实用的设计模式,特别是在需要解耦发送者和接收者的情况下。通过将请求封装成对象,不仅可以简化代码,还能提高系统的灵活性和可扩展性。在实际项目中,尤其是在需要处理异步操作或多线程环境时,命令模式的应用尤为广泛。