java设计模式:04-02-命令模式

命令模式 (Command Pattern)

命令模式是一种行为设计模式,它将请求封装成对象,从而使您可以用不同的请求、队列或日志来参数化其他对象。命令模式也支持可撤销的操作。

应用场景
  1. 事务处理系统:需要对一系列操作进行封装,并提供回滚功能。
  2. GUI开发:例如按钮点击的处理逻辑,可以使用命令模式将操作和按钮的点击事件解耦。
  3. 宏命令:组合多个操作命令,形成一个复合命令。
  4. 日志记录:在系统崩溃后,通过日志重现命令执行的过程。

实现方式

1. 基本命令模式

思想:将请求封装成独立的命令对象,使得命令的调用者与执行者解耦。

实现方式

java 复制代码
// 命令接口
interface Command {
    void execute();
}

// 具体命令
class LightOnCommand implements Command {
    private Light light;

    public LightOnCommand(Light light) {
        this.light = light;
    }

    public void execute() {
        light.on();
    }
}

// 接收者
class Light {
    public void on() {
        System.out.println("The light is on");
    }

    public void off() {
        System.out.println("The light is off");
    }
}

// 调用者
class RemoteControl {
    private Command command;

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

    public void pressButton() {
        command.execute();
    }
}

// 客户端代码
public class CommandPatternDemo {
    public static void main(String[] args) {
        Light light = new Light();
        Command lightOn = new LightOnCommand(light);

        RemoteControl remote = new RemoteControl();
        remote.setCommand(lightOn);
        remote.pressButton();
    }
}

优点

  • 解耦请求的发送者和接收者:使得发送者不需要知道接收者的具体实现。
  • 扩展性强:可以方便地新增命令。
  • 支持撤销操作:可以通过存储历史命令来支持撤销和重做操作。

缺点

  • 类的数量增加:每一个具体命令都需要一个对应的类。
2. 带撤销功能的命令模式

思想:在基本命令模式的基础上,增加对撤销操作的支持。

实现方式

java 复制代码
// 命令接口
interface Command {
    void execute();
    void undo();
}

// 具体命令
class LightOnCommand implements Command {
    private Light light;

    public LightOnCommand(Light light) {
        this.light = light;
    }

    public void execute() {
        light.on();
    }

    public void undo() {
        light.off();
    }
}

// 具体命令
class LightOffCommand implements Command {
    private Light light;

    public LightOffCommand(Light light) {
        this.light = light;
    }

    public void execute() {
        light.off();
    }

    public void undo() {
        light.on();
    }
}

// 接收者
class Light {
    public void on() {
        System.out.println("The light is on");
    }

    public void off() {
        System.out.println("The light is off");
    }
}

// 调用者
class RemoteControl {
    private Command command;

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

    public void pressButton() {
        command.execute();
    }

    public void pressUndo() {
        command.undo();
    }
}

// 客户端代码
public class CommandPatternDemo {
    public static void main(String[] args) {
        Light light = new Light();
        Command lightOn = new LightOnCommand(light);
        Command lightOff = new LightOffCommand(light);

        RemoteControl remote = new RemoteControl();
        remote.setCommand(lightOn);
        remote.pressButton();
        remote.pressUndo();

        remote.setCommand(lightOff);
        remote.pressButton();
        remote.pressUndo();
    }
}

优点

  • 支持撤销和重做操作:可以通过存储命令的历史记录来支持撤销和重做。
  • 解耦请求的发送者和接收者:发送者不需要知道接收者的具体实现。

缺点

  • 类的数量增加:每一个具体命令都需要一个对应的类。
  • 维护命令历史:需要额外的代码来维护命令历史。
3. 宏命令模式

思想:将多个命令组合成一个复合命令,使得一组命令可以一次执行。

实现方式

java 复制代码
// 命令接口
interface Command {
    void execute();
}

// 具体命令
class LightOnCommand implements Command {
    private Light light;

    public LightOnCommand(Light light) {
        this.light = light;
    }

    public void execute() {
        light.on();
    }
}

// 具体命令
class LightOffCommand implements Command {
    private Light light;

    public LightOffCommand(Light light) {
        this.light = light;
    }

    public void execute() {
        light.off();
    }
}

// 宏命令
class MacroCommand implements Command {
    private List<Command> commands;

    public MacroCommand() {
        commands = new ArrayList<>();
    }

    public void addCommand(Command command) {
        commands.add(command);
    }

    public void execute() {
        for (Command command : commands) {
            command.execute();
        }
    }
}

// 接收者
class Light {
    public void on() {
        System.out.println("The light is on");
    }

    public void off() {
        System.out.println("The light is off");
    }
}

// 客户端代码
public class MacroCommandPatternDemo {
    public static void main(String[] args) {
        Light light = new Light();
        Command lightOn = new LightOnCommand(light);
        Command lightOff = new LightOffCommand(light);

        MacroCommand macro = new MacroCommand();
        macro.addCommand(lightOn);
        macro.addCommand(lightOff);

        macro.execute();
    }
}

优点

  • 组合命令:可以将多个命令组合成一个复合命令,简化客户端代码。
  • 增强灵活性:可以动态添加或删除命令。

缺点

  • 类的数量增加:每一个具体命令都需要一个对应的类。
  • 命令依赖:命令之间可能存在依赖关系,需小心处理。

总结

命令模式 优点 缺点
基本命令模式 解耦请求的发送者和接收者,扩展性强 类的数量增加
带撤销功能的命令模式 支持撤销和重做操作,解耦请求的发送者和接收者 类的数量增加,维护命令历史
宏命令模式 组合命令,增强灵活性 类的数量增加,命令依赖

选择哪种实现方式应根据具体的需求和系统的复杂度来决定。基本命令模式适用于一般的请求封装场景,带撤销功能的命令模式适用于需要撤销和重做操作的场景,宏命令模式适用于需要组合多个操作的场景。通过合理的设计,可以充分利用命令模式的优势,解耦请求的发送者和接收者,提高系统的灵活性和可扩展性。

相关推荐
武子康11 分钟前
大数据-230 离线数仓 - ODS层的构建 Hive处理 UDF 与 SerDe 处理 与 当前总结
java·大数据·数据仓库·hive·hadoop·sql·hdfs
武子康13 分钟前
大数据-231 离线数仓 - DWS 层、ADS 层的创建 Hive 执行脚本
java·大数据·数据仓库·hive·hadoop·mysql
苏-言20 分钟前
Spring IOC实战指南:从零到一的构建过程
java·数据库·spring
界面开发小八哥27 分钟前
更高效的Java 23开发,IntelliJ IDEA助力全面升级
java·开发语言·ide·intellij-idea·开发工具
草莓base40 分钟前
【手写一个spring】spring源码的简单实现--容器启动
java·后端·spring
Allen Bright1 小时前
maven概述
java·maven
编程重生之路1 小时前
Springboot启动异常 错误: 找不到或无法加载主类 xxx.Application异常
java·spring boot·后端
薯条不要番茄酱1 小时前
数据结构-8.Java. 七大排序算法(中篇)
java·开发语言·数据结构·后端·算法·排序算法·intellij-idea
努力进修1 小时前
“探索Java List的无限可能:从基础到高级应用“
java·开发语言·list
politeboy1 小时前
k8s启动springboot容器的时候,显示找不到application.yml文件
java·spring boot·kubernetes