设计模式8-命令模式

定义

Command Partern: 将一个请求封装成一个对象,从而让你使用不同的请求把客户端参数化,对请求排队或者记录请求日志,可以提供命令的撤销和恢复功能。(核心思想是将"动作"与"执行者"解耦)

场景

  • GUI:操作将UI控件与业务逻辑解耦,一个命令可被多处复用。

  • 撤销/重做:通过记录命令历史和状态,实现操作的回逆。

  • 任务队列:实现任务的延迟执行和异步处理,解耦生产与消费。

  • 宏录制:使用组合模式将多个命令组合成一个宏命令。

  • 事务系统:提供原子操作和回滚机制。

  • 异步回调:封装未来需要执行的操作,实现模块间的解耦通信。

Java中的典型场景

  1. Swing/AWT事件处理:ActionListener本质是命令模式。

  2. 线程池:RunnableCallable任务封装了执行逻辑。

  3. 事务管理:数据库操作封装为可回滚的命令对象。

代码

java 复制代码
import java.util.Stack;
// 文档编辑器的撤销和执行
// 命令接口
interface EditorCommand {
    void execute();
    void undo();
}

// 接收者:文档
class Document {
    private StringBuilder content = new StringBuilder();

    public String getContent() {
        return content.toString();
    }

    public void insertText(String text) {
        content.append(text);
        System.out.println("插入文本: " + text + ",当前内容: " + content);
    }

    public void deleteText(int length) {
        if (length > content.length()) {
            length = content.length();
        }
        String deleted = content.substring(content.length() - length);
        content.delete(content.length() - length, content.length());
        System.out.println("删除文本: " + deleted + ",当前内容: " + content);
    }
}

// 具体命令:插入文本
class InsertCommand implements EditorCommand {
    private Document document;
    private String text;

    public InsertCommand(Document doc, String text) {
        this.document = doc;
        this.text = text;
    }

    @Override
    public void execute() {
        document.insertText(text);
    }

    @Override
    public void undo() {
        document.deleteText(text.length());
    }
}

// 调用者:编辑器
class TextEditor {
    private Stack<EditorCommand> commandHistory = new Stack<>();
    private Stack<EditorCommand> redoStack = new Stack<>();

    public void executeCommand(EditorCommand command) {
        command.execute();
        commandHistory.push(command);
        redoStack.clear(); // 执行新命令后清空重做栈
    }

    public void undo() {
        if (!commandHistory.isEmpty()) {
            EditorCommand command = commandHistory.pop();
            command.undo();
            redoStack.push(command);
            System.out.println("执行撤销操作");
        } else {
            System.out.println("没有可撤销的操作");
        }
    }

    public void redo() {
        if (!redoStack.isEmpty()) {
            EditorCommand command = redoStack.pop();
            command.execute();
            commandHistory.push(command);
            System.out.println("执行重做操作");
        } else {
            System.out.println("没有可重做的操作");
        }
    }
}

// 测试类
 class TextEditorDemo {
    public static void main(String[] args) {
        Document doc = new Document();
        TextEditor editor = new TextEditor();

        System.out.println("=== 编辑文档过程 ===");
        editor.executeCommand(new InsertCommand(doc, "Hello "));
        editor.executeCommand(new InsertCommand(doc, "World "));
        editor.executeCommand(new InsertCommand(doc, "Java!"));

        System.out.println("\n=== 撤销操作 ===");
        editor.undo(); // 撤销插入"Java!"
        editor.undo(); // 撤销插入"World "

        System.out.println("\n=== 重做操作 ===");
        editor.redo(); // 重做插入"World "
        editor.redo(); // 重做插入"Java!"
    }
}
    

生活中的示例:文档编辑器撤销 (Undo) 和重做 (Redo) 功能,比如餐厅点餐系统的例子:服务员(调用者)接收顾客的点单(命令),然后交给厨房(接收者)执行。在比如家电遥控器:遥控器上的每个按钮都对应一个命令,按下按钮就执行相应操作(开、关、调节等)

命令模式代码

相关推荐
workflower1 小时前
例二:某汽车制造企业深度融合AI智能体,构建园区网络的智能运维体系
人工智能·机器学习·设计模式·机器人·云计算·汽车·制造
ly76892 小时前
Java 设计模式详解:从原则到 23 种经典模式
java·开发语言·设计模式
AI人工智能+电脑小能手5 小时前
大白话说Java设计模式-14-适配器模式(业务实战篇)
java·设计模式·适配器模式·系统兼容·多渠道对接
略略略咯咯13 小时前
(总结)设计模式
设计模式
Cosolar1 天前
DeepSeek Harness 理解 Harness 的设计哲学 - 可组合的插件运行时
人工智能·设计模式·架构
Nebula_g1 天前
JavaSE基础语法:特殊类(特殊情景下的设计模式)
java·开发语言·设计模式
George_Ye2 天前
同一本书,一人一份:我如何设计 AI 个性化扫书报告
设计模式
莫得感情 o2 天前
设计模式 22 · 三个冷门模式:中介者、访问者、解释器
java·设计模式
AI人工智能+电脑小能手3 天前
大白话说Java设计模式-08-建造者模式(业务实战篇)
java·设计模式·建造者模式·架构设计·对象构建
AustinXu3 天前
从 Claude Code 到 Claude Tag,Harness Engineering 走到了组织这一层
设计模式·团队管理