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

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

相关推荐
魔道不误砍柴功2 小时前
Java 中如何巧妙应用 Function 让方法复用性更强
java·开发语言·python
NiNg_1_2342 小时前
SpringBoot整合SpringSecurity实现密码加密解密、登录认证退出功能
java·spring boot·后端
闲晨2 小时前
C++ 继承:代码传承的魔法棒,开启奇幻编程之旅
java·c语言·开发语言·c++·经验分享
测开小菜鸟3 小时前
使用python向钉钉群聊发送消息
java·python·钉钉
P.H. Infinity4 小时前
【RabbitMQ】04-发送者可靠性
java·rabbitmq·java-rabbitmq
生命几十年3万天4 小时前
java的threadlocal为何内存泄漏
java
caridle5 小时前
教程:使用 InterBase Express 访问数据库(五):TIBTransaction
java·数据库·express
^velpro^5 小时前
数据库连接池的创建
java·开发语言·数据库
苹果醋35 小时前
Java8->Java19的初步探索
java·运维·spring boot·mysql·nginx
秋の花5 小时前
【JAVA基础】Java集合基础
java·开发语言·windows