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

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

相关推荐
多多*3 分钟前
计算机网络相关 讲一下rpc与传统http的区别
java·开发语言·网络·jvm·c#
源码获取_wx:Fegn08955 分钟前
计算机毕业设计|基于springboot + vue网上超市系统(源码+数据库+文档)
java·数据库·vue.js·spring boot·后端·spring·课程设计
码农水水6 分钟前
阿里Java面试被问:Online DDL的INSTANT、INPLACE、COPY算法差异
java·服务器·前端·数据库·mysql·算法·面试
小旭95277 分钟前
【Java 基础】IO 流 全面详解
java·开发语言
Coder_Boy_10 分钟前
基于SpringAI的在线考试系统-阅卷评分与错题管理模块回归测试逻辑梳理文档
java·spring boot·系统架构·ddd·tdd·全栈开发
那起舞的日子11 分钟前
Java线程池-执行顺序
java
先做个垃圾出来………12 分钟前
Linux/Unix系统下的基础文本处理命令
java·linux·unix
风若飞12 分钟前
Linux 环境下解决 Tomcat8 与 JDK8 配置问题
java·linux·运维·服务器·tomcat
ONExiaobaijs14 分钟前
Java jdk运行库合集
java·开发语言·python
Coder_Boy_25 分钟前
基于SpringAI的在线考试系统-教学管理与用户管理模块联合回归测试文档
java·前端·数据库·人工智能·spring boot