23种设计模式之:命令模式

命令模式是一种行为设计模式,它将一个请求封装成一个对象,从而让你使用不同的请求、队列或者请求的日志来参数化其他对象。它也支持可撤销的操作。命令模式的关键是引入了抽象层------命令接口,具体命令实现该接口,执行操作的对象从执行具体操作的职责中解耦出来。

使用场景

  • 当你需要参数化对象根据请求来执行操作时,可以使用命令模式,因为它可以指定和执行请求。
  • 当你需要在不同的时间指定、排队和执行请求时。命令对象可以在一个队列中排队,并在稍后执行。
  • 当需要支持撤销操作时。命令模式可以将状态回滚到某个命令被执行之前的状态。
  • 当你需要将操作组装成复杂操作时,可以使用命令模式,它支持组合命令。

好处

  • 降低耦合度:命令模式通过引入命令接口,使得请求的发送者和接收者解耦,增加新的命令很方便,不需要改动旧的代码。
  • 增强可扩展性:可以很容易地添加新命令,只需实现接口即可。
  • 支持撤销操作:可以通过实现撤销方法来轻松支持撤销。
  • 可以组合命令:可以将多个命令组装成宏命令,一次性执行多个操作。

Java代码演示

接收者(Receiver)

接收者类Light实际执行与请求相关的操作:

java 复制代码
public class Light {
    public void turnOn() {
        System.out.println("Light is on");
    }

    public void turnOff() {
        System.out.println("Light is off");
    }
}

命令接口(Command)

命令接口定义了执行操作的方法:

java 复制代码
public interface Command {
    void execute();
}

具体命令(Concrete Commands)

具体命令实现命令接口,并定义接收者和操作之间的绑定关系:

java 复制代码
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();
    }
}

调用者(Invoker)

调用者持有命令对象,并在某个时间点调用命令对象的execute()方法:

java 复制代码
public class RemoteControl {
    private Command command;

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

    public void pressButton() {
        if (command != null) {
            command.execute();
        }
    }
}

客户端(Client)

客户端决定哪个命令执行,以及它的接收者是谁:

java 复制代码
public class Client {
    public static void main(String[] args) {
        // 创建接收者
        Light light = new Light();

        // 创建命令,并设置其接收者
        Command lightsOn = new LightOnCommand(light);
        Command lightsOff = new LightOffCommand(light);

        // 创建调用者,并关联命令
        RemoteControl control = new RemoteControl();
        control.setCommand(lightsOn); // 设置开灯命令
        control.pressButton(); // 执行开灯命令

        control.setCommand(lightsOff); // 设置关灯命令
        control.pressButton(); // 执行关灯命令
    }
}

命令模式的好处

通过这个更完整的示例,我们可以看到命令模式的几个关键好处:

  • 解耦调用操作和接收者RemoteControl(调用者)不直接操作Light(接收者),而是通过命令对象进行间接操作。这意味着Light类的任何变化都不会直接影响到RemoteControl类,反之亦然。
  • 易于扩展 :要增加新的命令操作,只需添加一个新的Command实现即可,无需修改现有的InvokerReceiver类。
  • 组合命令:可以很容易地实现宏命令,即一个命令触发多个操作。

这样,使用命令模式提供了代码的灵活性和扩展性,同时也使得操作的撤销和重做成为可能。

相关推荐
机灵猫19 小时前
深入理解 Java 类加载与垃圾回收机制:从原理到实践
java·开发语言
Sunsets_Red19 小时前
差分操作正确性证明
java·c语言·c++·python·算法·c#
QZ_orz_freedom19 小时前
学习笔记--文件上传
java·笔记·学习
焰火199919 小时前
[Java][SpringBoot]集成Redis实现Session共享
java·redis
荣淘淘19 小时前
互联网大厂Java求职面试全景实战解析(涵盖Spring Boot、微服务及云原生技术)
java·spring boot·redis·jwt·cloud native·microservices·interview
超龄超能程序猿19 小时前
Spring AI Alibaba 与 Ollama对话历史的持久化
java·人工智能·spring
hrrrrb19 小时前
【Spring Security】认证(二)
java·后端·spring
33255_40857_2805919 小时前
告别密码爆破!手把手教你用注解和拦截器实现登录限流
java
舒克日记20 小时前
基于springboot针对老年人的景区订票系统
java·spring boot·后端