命令模式(Command Pattern)

title

命令模式(Command Pattern)是一种行为型设计模式,它将请求封装为一个对象,从而让你可用不同的请求对客户端进行参数化,对请求排队或记录请求日志,以及支持可撤销的操作。命令模式将调用操作的对象和知道如何实现该操作的对象解耦。

命令模式包含以下几个角色:

  • Command:命令接口,定义执行命令的方法 execute。
  • ConcreteCommand:具体的命令类,实现 Command 接口,封装了命令的执行者和参数。
  • Invoker:调用者,负责调用命令对象执行命令。
  • Receiver:接收者,知道如何实现命令所要求的操作,任何类都可以成为一个接收者。
  • Client:客户端,创建具体的命令对象并设置其接收者。

下面是一个简单的例子来说明命令模式:


// Receiver
class Light {
    public void on() {
        System.out.println("灯已打开!");
    }

    public void off() {
        System.out.println("灯已关闭!");
    }
}

// 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.on();
    }
}

class LightOffCommand implements Command {
    private Light light;

    public LightOffCommand(Light light) {
        this.light = light;
    }

    @Override
    public void execute() {
        light.off();
    }
}

// Invoker
class RemoteControl {
    private Command command;

    public void setCommand(Command command) {
        this.command = command;
    }

    public void pressButton() {
        command.execute();
    }
}

// Client
public class Client {
    public static void main(String[] args) {
        Light light = new Light();

        Command lightOnCommand = new LightOnCommand(light);
        Command lightOffCommand = new LightOffCommand(light);

        RemoteControl remoteControl = new RemoteControl();
        remoteControl.setCommand(lightOnCommand);
        remoteControl.pressButton();

        remoteControl.setCommand(lightOffCommand);
        remoteControl.pressButton();
    }
}

在这个示例中,我们使用命令模式来控制灯的开关。Light 类是接收者,负责执行灯的打开和关闭操作。Command 接口定义了命令的执行方法 execute。LightOnCommand 和 LightOffCommand 类是具体的命令类,它们实现了 Command 接口,将灯的打开和关闭操作封装在命令对象中。RemoteControl 类是调用者,负责调用命令对象执行命令。Client 类创建具体的命令对象并设置其接收者。

在客户端代码中,我们首先创建一个 Light 对象,然后创建 LightOnCommand 和 LightOffCommand 对象,并分别将它们设置为 RemoteControl的命令对象。最后,我们调用 RemoteControl 对象的 pressButton 方法来执行命令。

命令模式的优点在于它能够让请求的发送者和接收者解耦,请求发送者只需要知道如何发送请求,而不需要知道请求是如何被接收和处理的。此外,命令模式还可以将多个命令对象组合成一个复合命令,以实现批处理等功能。另外,命令模式还可以支持撤销操作,只需在命令对象中添加一个 undo 方法即可。

命令模式的缺点在于它可能会导致类的数量增加,特别是在有多个接收者的情况下。此外,命令模式还可能导致代码复杂化,因为需要定义多个类来封装不同的命令操作。

下面是命令模式的 UML 类图:

+------------------+       +------------------------+       +----------------+
|    Command       |       |        Receiver        |       |    Invoker     |
+------------------+       +------------------------+       +----------------+
| + execute()      |       | + action()             |       | + setCommand() |
+------------------+       +------------------------+       | + pressButton()|
         △                       △                        +----------------+
         |                        |                                 △
+------------------+      +---------------------+                   |
| ConcreteCommand1 |      |   ConcreteCommand2  |                   |
+------------------+      +---------------------+                   |
| + execute()      |      | + execute()         |                   |
+------------------+      +---------------------+                   |
         △                       △                                |
         |                        |                                 |
+------------------+      +----------------------+                  |
|      Client      |      |        Receiver2     |                  |
+------------------+      +----------------------+                  |
|                  |      | + action()           |                  |
|                  |      +----------------------+                  |
|                  |                                                |
|                  |                                                |
| + main()         |                                                |
+------------------+

在上述 UML 类图中,Command 是命令的接口,它定义了命令对象需要实现的方法 execute()。ConcreteCommand1 和 ConcreteCommand2 是具体的命令类,它们实现了 Command 接口,并封装了命令的接收者对象。Invoker 是调用者,它负责调用命令对象的 execute() 方法。Receiver 是接收者,它定义了命令所需的操作。Client 是客户端,它创建具体的命令对象并设置其接收者。

powered by Gitbook© 2023 编外计划 | 最后修改: 2023-11-24 03:37:01

results matching ""

    No results matching ""