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

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

相关推荐
辰烨chenye1 小时前
LeetCode Hot 100 题解 · 堆篇
java·算法·leetcode
shehuiyuelaiyuehao2 小时前
算法29,前缀和,除自身以外的数组的乘积
java·数据结构·算法
小刘在重生~2 小时前
Java常用类|String类详解 + BigDecimal精准计算(含面试题)
java·开发语言·python
随遇而安zx2 小时前
【多线程】---JMM 与 volatile 深度解析
java·多线程
邪修king2 小时前
Re:Linux系统篇(十九):进程篇(八): 进程等待详解:wait/waitpid,僵尸进程到底该如何回收
java·开发语言
啵啵啵鱼3 小时前
DS-顺序表
java·数据结构·笔记·后端·链表·obsidian
TinyMemory3 小时前
Java 面向对象核心入门(七):方法重载 Overload,同一个方法名能干不一样的活
java·面向对象·overload·方法重载
吴声子夜歌3 小时前
Java扩展——OkHttp
java·开发语言·okhttp
卓怡学长3 小时前
w210基于springboot反诈平台设计与实现
java·spring boot·spring·intellij-idea