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类。
  • 组合命令:可以很容易地实现宏命令,即一个命令触发多个操作。

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

相关推荐
37.2℃9958 分钟前
Claude Design哪个公司技术好
python·设计模式
凤山老林22 分钟前
SpringBoot实战:构建优雅的全局异常处理机制
java·springboot·异常处理
小Ti客栈43 分钟前
Spring Boot 整合 Swagger2 和 Knife4j实现接口文档与可视化调试
java·spring boot·后端
梅头脑1 小时前
ThreadLocalMap里几十万个死Entry——排查了半天OOM,根因就一行finally没写
java
阿懂在掘金1 小时前
Vue 弹窗新范式——代码减少、复用翻倍与 AI 时代的前端基建
前端·设计模式·前端框架
2601_963870171 小时前
【计算机毕业设计】基于Spring Boot的社区老年大学课程报名与学习系统的设计与实现
java·spring boot·学习
llwszx2 小时前
【Java/Go后端手撸原生Agent(第七篇):Token预算管理 + 滑动窗口上下文裁剪】
java·后端·python·agent开发·上下文工程·上下文裁剪·滑动窗口裁剪
weixin_BYSJ19872 小时前
springboot3家政平台小程序--附源码00904
java·javascript·spring boot·python·django·flask·php
梦幻通灵3 小时前
Java中finally失效的几种情况【持续更新】
java·开发语言
月落归舟3 小时前
SpringMVC 多种响应返回方式
java·开发语言