23种设计模式之【命令模式】-核心原理与 Java 实践

文章目录

  • [命令模式(Command Pattern)](#命令模式(Command Pattern))
  • 核心原理
  • [Java 实践示例](#Java 实践示例)
  • 运行结果
  • 命令模式的核心价值
  • [命令模式在 GUI 操作、事务管理、任务调度等场景中应用广泛,例如:](#命令模式在 GUI 操作、事务管理、任务调度等场景中应用广泛,例如:)

命令模式(Command Pattern)

命令模式是 23 种设计模式中的一种行为型模式,其核心思想是将请求封装为一个对象(命令),从而使你可以用不同的请求对客户进行参数化,并且支持请求的排队、记录日志、撤销等操作。

核心原理

命令接口(Command):

声明执行操作的方法(通常是execute())

可选地声明撤销操作的方法(undo())
具体命令(ConcreteCommand):

实现命令接口,持有接收者(Receiver)的引用

在execute()方法中调用接收者的具体操作

若支持撤销,需在undo()中实现反向操作
接收者(Receiver):

知道如何执行与请求相关的操作,是实际业务逻辑的执行者

与命令解耦,不关心命令的存在
调用者(Invoker):

持有命令对象,负责触发命令的执行

不关心命令的具体实现和接收者是谁
客户端(Client):

创建具体命令对象,并设置其接收者

决定哪个命令与哪个接收者关联

命令模式的核心是 "封装请求",将发出请求的责任和执行请求的责任分割开,通过命令对象连接两者。

Java 实践示例

下面以 "遥控器控制家电" 为例实现命令模式:

遥控器(调用者)可执行各种命令(开 / 关灯光、开 / 关电视)

支持命令的执行和撤销操作

bash 复制代码
package com.example.demo;

public class CommandPattern {
    public static void main(String[] args) {
        // 创建接收者(家电)
        Light livingRoomLight = new Light("客厅");
        TV livingRoomTV = new TV("客厅");

        // 创建命令
        Command lightOn = new LightOnCommand(livingRoomLight);
        Command lightOff = new LightOffCommand(livingRoomLight);
        Command tvOn = new TVOnCommand(livingRoomTV);
        Command tvOff = new TVOffCommand(livingRoomTV);

        // 创建调用者(遥控器)
        RemoteControl remote = new RemoteControl();

        // 执行命令
        System.out.println("--- 执行命令 ---");
        remote.setCommand(lightOn);
        remote.pressButton();

        remote.setCommand(tvOn);
        remote.pressButton();

        // 撤销命令
        System.out.println("\n--- 撤销命令 ---");
        remote.pressUndoButton();
        remote.pressUndoButton();

        // 再次执行关闭命令
        System.out.println("\n--- 执行关闭命令 ---");
        remote.setCommand(lightOff);
        remote.pressButton();
    }

    public interface Command {
        void execute();
        void undo();
    }

    // 灯光接收者
    public static class Light {
        private String location;
        private boolean isOn;

        public Light(String location) {
            this.location = location;
        }

        public void on() {
            isOn = true;
            System.out.println(location + "灯光已打开");
        }

        public void off() {
            isOn = false;
            System.out.println(location + "灯光已关闭");
        }
    }

    // 电视接收者
    public static class TV {
        private String location;
        private boolean isOn;

        public TV(String location) {
            this.location = location;
        }

        public void on() {
            isOn = true;
            System.out.println(location + "电视已打开");
        }

        public void off() {
            isOn = false;
            System.out.println(location + "电视已关闭");
        }
    }

    // 开灯命令
    public static class LightOnCommand implements Command {
        private Light light;

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

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

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

    // 关灯命令(其他命令类似)
    public static class LightOffCommand implements Command {
        private Light light;
        public LightOffCommand(Light light) {
            this.light = light;
        }
        // 实现代码类似,execute()调用light.off(),undo()调用light.on()
        @Override
        public void execute() {
            light.off();
        }

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

    public static class TVOnCommand implements Command {
        // 持有电视接收者的引用
        private TV tv;

        // 通过构造函数注入接收者
        public TVOnCommand(TV tv) {
            this.tv = tv;
        }

        // 执行命令:调用电视的打开方法
        @Override
        public void execute() {
            tv.on();
        }

        // 撤销命令:对应的反向操作是关闭电视
        @Override
        public void undo() {
            tv.off();
        }
    }

    public static class TVOffCommand implements Command {
        // 持有电视接收者的引用,通过构造函数注入
        private TV tv;

        public TVOffCommand(TV tv) {
            this.tv = tv;
        }

        // 执行命令:调用电视的关闭方法
        @Override
        public void execute() {
            tv.off();
        }

        // 撤销命令:对应的反向操作是打开电视
        @Override
        public void undo() {
            tv.on();
        }
    }


    public static class RemoteControl {
        private Command command;
        private Command lastCommand; // 用于撤销操作

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

        // 执行命令
        public void pressButton() {
            command.execute();
            lastCommand = command; // 记录最后执行的命令
        }

        // 撤销命令
        public void pressUndoButton() {
            if (lastCommand != null) {
                lastCommand.undo();
            }
        }
    }
}

运行结果

--- 执行命令 ---

客厅灯光已打开

客厅电视已打开

--- 撤销命令 ---

客厅电视已关闭

客厅灯光已关闭

--- 执行关闭命令 ---

客厅灯光已关闭

命令模式的核心价值

解耦发送者和接收者:调用者无需知道接收者是谁以及如何执行操作

支持命令队列和批处理:可以将多个命令组合成宏命令一次性执行

支持撤销和重做:通过记录命令历史实现操作回滚

支持日志记录:可以记录命令执行日志,用于审计或故障恢复

命令模式在 GUI 操作、事务管理、任务调度等场景中应用广泛,例如:

文本编辑器的撤销 / 重做功能

数据库事务的提交 / 回滚

任务调度框架中的任务封装

遥控器、菜单等交互组件的命令封装

相关推荐
Cosolar9 小时前
DeepSeek Harness 理解 Harness 的设计哲学 - 可组合的插件运行时
人工智能·设计模式·架构
Nebula_g10 小时前
JavaSE基础语法:特殊类(特殊情景下的设计模式)
java·开发语言·设计模式
George_Ye1 天前
同一本书,一人一份:我如何设计 AI 个性化扫书报告
设计模式
莫得感情 o1 天前
设计模式 22 · 三个冷门模式:中介者、访问者、解释器
java·设计模式
AI人工智能+电脑小能手2 天前
大白话说Java设计模式-08-建造者模式(业务实战篇)
java·设计模式·建造者模式·架构设计·对象构建
AustinXu2 天前
从 Claude Code 到 Claude Tag,Harness Engineering 走到了组织这一层
设计模式·团队管理
剧中有戏2 天前
单例模式从入门到精通:一个数据库连接池的完整剖析
设计模式
胡萝卜术2 天前
编译期与运行期的双重防线:从 TypeScript 类型之争到 LLM 输出的自动化择优
前端·设计模式·面试
货拉拉技术2 天前
重塑 Agent 度量衡:基于 LLM-as-a-Judge 的离线评估体系与实践
算法·设计模式
KhalilRuan2 天前
设计模式小记
设计模式