Java设计模式之行为型模式(命令模式)介绍与说明

一、核心定义与目标

命令模式通过对象化请求,将操作的具体实现细节隐藏在命令对象中,使得调用者(Invoker)无需直接与接收者(Receiver)交互,仅需通过命令对象间接调用。这种解耦设计支持以下功能:

  1. 请求队列化:命令对象可存储、传递并按需执行。
  2. 撤销与重做:通过记录命令历史实现操作回滚。
  3. 日志记录与事务支持:便于追踪和恢复系统状态。

二、模式结构与角色

命令模式涉及以下核心角色:

  1. Command(抽象命令接口)
    定义执行命令的统一接口,通常包含execute()方法。

    java 复制代码
    public interface Command { 
        void execute(); 
    }
  2. ConcreteCommand(具体命令类)
    实现Command接口,持有接收者(Receiver)的引用,并调用其具体方法。

    java 复制代码
    public class LightOnCommand implements Command {
        private Light light;
        public LightOnCommand(Light light) { this.light = light; }
        public void execute() { light.turnOn(); }
    }
  3. Receiver(接收者)
    实际执行操作的对象,例如电灯、音响设备等。

    java 复制代码
    public class Light {
        public void turnOn() { System.out.println("开灯"); }
    }
  4. Invoker(调用者)
    负责触发命令的执行,但不关心命令的具体实现。

    java 复制代码
    public class RemoteControl {
        private Command command;
        public void setCommand(Command command) { this.command = command; }
        public void pressButton() { command.execute(); }
    }
  5. Client(客户端)
    创建具体命令对象并关联接收者,将其传递给调用者。


三、代码示例与实现

场景:遥控器控制电灯

  1. 定义接收者

    java 复制代码
    class Light {
        public void on() { System.out.println("灯开启"); }
        public void off() { System.out.println("灯关闭"); }
    }
  2. 实现具体命令

    java 复制代码
    class LightOnCommand implements Command {
        private Light light;
        public LightOnCommand(Light light) { this.light = light; }
        public void execute() { light.on(); }
    }
  3. 调用者与客户端

    java 复制代码
    public class Client {
        public static void main(String[] args) {
            Light light = new Light();
            Command command = new LightOnCommand(light);
            RemoteControl control = new RemoteControl();
            control.setCommand(command);
            control.pressButton(); // 输出:灯开启
        }
    }

    结果:通过调用者间接控制接收者,实现解耦。


四、高级应用场景

  1. 宏命令(Macro Command)
    将多个命令组合成一个复合命令,例如批量执行操作:

    java 复制代码
    class MacroCommand implements Command {
        private List commands = new ArrayList<>();
        public void add(Command cmd) { commands.add(cmd); }
        public void execute() { commands.forEach(Command::execute); }
    }
  2. 撤销与重做(Undo/Redo)
    通过扩展命令对象的undo()方法实现撤销功能:

    java 复制代码
    public interface UndoableCommand extends Command {
        void undo();
    }
  3. 异步命令队列
    结合线程池处理异步任务,提升系统吞吐量。


五、优缺点分析

优点 缺点
解耦请求发送者与接收者,提升灵活性 可能导致类爆炸问题(每个命令需独立类)
支持扩展新命令,符合开闭原则 增加系统复杂度,需额外管理命令对象
便于实现撤销、日志记录等高级功能 过度设计风险,简单场景可能不必要

六、适用场景

  1. 需要将请求参数化或延迟执行(如GUI按钮点击)。
  2. 需支持撤销/重做操作(如文本编辑器)。
  3. 系统需记录操作日志或实现事务管理。

七、与其他模式的对比

策略模式:关注算法替换,而命令模式关注请求封装。

  • 观察者模式:通过订阅-发布机制解耦,而命令模式通过对象化请求解耦。

总结

命令模式通过对象化请求实现了灵活的调用机制,是构建可扩展、可维护系统的利器。但在实际应用中需权衡其复杂性,避免滥用。结合具体场景(如撤销操作、异步任务)选择是否引入该模式,可显著提升代码的解耦性与扩展性。

相关推荐
特立独行的猫A3 小时前
用仓颉语言 cj-tauri 框架,五分钟给娃做了个鸿蒙形近字游戏
java·后端·python
Rabitebla8 小时前
【Linux】进程控制(十二) 自定义 Shell(二):内建命令与进程工作目录管理
linux·c++·笔记·学习·bash
Gary移动存储固件9 小时前
eMMC5.1协议中文学习讲解(6.6.17~6.6.22.4.6)
学习·ufs·emmc·nand·存储固件
budingxiaomoli9 小时前
Spring统一功能处理
java·后端·spring
一个天蝎座 白勺 程序猿10 小时前
别让收藏夹替你学习:我搭AI知识体系的完整方法,脚本直接拿去用
人工智能·学习·ai·ai学习
是2的10次方啊10 小时前
设计模式与生活㉑:一句“建议复查”,是好几句话拼出来的
设计模式
楚山之石10 小时前
【Nat Biomed Eng】Connectome 2.0 超高梯度扫描仪:500 mT/m 与 600 T/m/s 把活体人脑微观结构分辨推进到亚微米级
图像处理·学习·数据分析·mri
Flynn Liang11 小时前
可观测性与成本治理:一次对话的 17 个观测点
java·langchain·可观测性·micrometer·langchain4j·token 成本·llm 监控
金銀銅鐵11 小时前
带您看懂字节码指令(三):同一行加法,为什么有四种指令
java·jvm
坤坤子吖13 小时前
Linux网络编程:TCP 粘包与半包问题,如何正确处理 TCP 流式数据?
linux·服务器·网络·笔记·网络协议·学习