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();
    }
}

优点:

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

缺点:

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

总结

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

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

相关推荐
余额瞒着我当琳4 分钟前
哈希表底层原理解析,直接定址法,哈希冲突,负载因子,哈希函数,开放定址法
java·c++·哈希算法·散列表
paopaokaka_luck41 分钟前
民宿管理系统 (AI民宿总结、协同过滤推荐算法、WebSocket 在线咨询、ECharts 经营分析、房态与结算联动、 民宿预订业务闭环)
java·人工智能·spring boot·websocket·数据分析·echarts·推荐算法
java资料站1 小时前
十四、Spring AI Alibaba · 案例 · 基于 HumanInTheLoop 的内容审核系统
java·spring·状态模式
geovindu1 小时前
rust: Iterator Pattern
开发语言·后端·设计模式·rust·行为模式·迭代器模
SunnyDays10112 小时前
如何使用 Java 提取 PPT 中的文字:整份文档、指定幻灯片与表格内容
java·powerpoint
毕设单片机2 小时前
springboot志愿服务平台的设计与实现 36731
java·spring boot·mysql·志愿服务平台
IT_Octopus2 小时前
【零基础入门 LLM 开发 · Day 15】:LangChain 注册工具——告别手写 JSON Schema
java·langchain·json
Elastic 中国社区官方博客2 小时前
教程:监控 Java 应用
java·开发语言·数据库·elasticsearch·搜索引擎·全文检索
ShineWinsu2 小时前
对于JavaScript:初识JavaScript以及输入输出
java·开发语言·前端·javascript·css·面试·html