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 操作、事务管理、任务调度等场景中应用广泛,例如:

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

数据库事务的提交 / 回滚

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

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

相关推荐
在未来等你8 小时前
AI Agent设计模式 Day 19:Feedback-Loop模式:反馈循环与自我优化
设计模式·llm·react·ai agent·plan-and-execute
兵bing13 小时前
设计模式-访问者模式
设计模式·访问者模式
python零基础入门小白13 小时前
【万字长文】大模型应用开发:意图路由与查询重写设计模式(从入门到精通)
java·开发语言·设计模式·语言模型·架构·大模型应用开发·大模型学习
MC丶科13 小时前
Java设计模式漫画英雄宇宙-工厂模式 —Factory博士的“超级英雄制造机”!
java·设计模式·漫画
明洞日记14 小时前
【设计模式手册013】命令模式 - 请求封装的优雅之道
java·设计模式·命令模式
ada0_ada114 小时前
行为型模式:②命令模式(Command Pattern)
设计模式
o0向阳而生0o15 小时前
113、23种设计模式之中介者模式(21/23)
设计模式·中介者模式
心语星光15 小时前
23种经典设计模式
设计模式
ACE19851 天前
AI Agent 设计模式深度解析:提示链(Prompt Chaining)模式
人工智能·设计模式·prompt
明洞日记2 天前
【设计模式手册012】责任链模式 - 请求处理的流水线艺术
java·设计模式·责任链模式