首页 > 其他分享 >设计模式之命令模式

设计模式之命令模式

时间:2025-01-14 09:01:11浏览次数:3  
标签:void 模式 命令 clipboard editor 撤销 设计模式 public

命令模式(Command Pattern)是一种行为型设计模式。它将一个请求封装为一个对象,从而使你可以用不同的请求对客户进行参数化,对请求排队或者记录请求日志,以及支持可撤销的操作。

简单来说,命令模式就像是一个餐厅的点菜系统。顾客(客户端)发出点菜的请求(命令),服务员(调用者)接收这个请求并将其记录为一个订单(命令对象),然后厨房(接收者)根据这个订单进行烹饪。这里的订单就是封装了顾客请求的对象。

主要特性:

  • 封装请求: 将一个请求封装成一个对象,从而允许你使用不同的请求对客户进行参数化。
  • 解耦发送者和接收者: 发送者(调用方)与接收者(执行具体操作的对象)之间是完全解耦的,它们通过命令对象进行交互。
  • 支持撤销/重做: 可以很容易地添加撤销或重做的功能,因为每个命令都保存了足够的信息来实现这些功能。
  • 命令队列: 容易实现命令队列和日志记录,使得系统能够处理延迟执行或异步执行的命令。

一、工作中的应用场景

  • 图形用户界面(GUI)应用:在 GUI 应用中,菜单选项和按钮的操作通常是使用命令模式实现的。例如,在一个文字处理软件中,“新建文档”“打开文件”“保存文件” 等菜单选项都是命令。当用户点击 “保存文件” 按钮(调用者)时,就会执行一个 “保存文件” 命令(命令对象)。这个命令对象知道如何调用文件存储系统(接收者)来保存当前文档的内容。这种设计使得界面操作和实际的业务逻辑(文件存储、读取等)分离开来,便于维护和扩展。同时,一些高级的 GUI 应用还支持撤销和重做操作,这也是通过命令模式实现的。每次用户执行一个操作(如修改字体、插入图片),都会创建一个相应的命令对象,这些命令对象被存储在一个栈中,用于支持撤销和重做操作。
  • 事务处理系统:在企业级的事务处理系统中,如银行的交易系统,每一笔交易(如存款、取款、转账)都可以看作是一个命令。客户通过 ATM 机或者网上银行(调用者)发起交易请求,这个请求被封装为一个交易命令(命令对象)。银行的核心交易处理系统(接收者)会根据这个命令执行相应的操作,如更新账户余额、记录交易日志等。命令模式使得银行可以很容易地对交易进行排队、记录和撤销,确保交易的准确性和安全性。

二、编程实现

下面是一个使用Java编写的命令模式示例程序,它演示了如何通过命令模式来实现一个简单的文本编辑器的功能,包括复制、粘贴和撤销操作。

2.1 定义命令接收者

// 接收者类 - 定义了具体的业务逻辑
class TextEditor {
    private String clipboard = ""; // 用于保存剪贴板内容

    public void copy(String text) {
        System.out.println("Copying text: " + text);
        this.clipboard = text;
    }

    public void paste() {
        if (!clipboard.isEmpty()) {
            System.out.println("Pasting text: " + clipboard);
        } else {
            System.out.println("Clipboard is empty, nothing to paste.");
        }
    }

    public void clearClipboard() {
        System.out.println("Clearing clipboard.");
        this.clipboard = "";
    }
}

2.2 定义命令接口及对象

// 抽象命令接口
interface Command {
    void execute(); // 执行命令
    void undo();    // 撤销命令
}

// 具体命令类 - 复制命令
class CopyCommand implements Command {
    private TextEditor editor;
    private String textToCopy;

    public CopyCommand(TextEditor editor, String textToCopy) {
        this.editor = editor;
        this.textToCopy = textToCopy;
    }

    @Override
    public void execute() {
        editor.copy(textToCopy);
    }

    @Override
    public void undo() {
        editor.clearClipboard();
    }
}

// 具体命令类 - 粘贴命令
class PasteCommand implements Command {
    private TextEditor editor;
    private String previousContent;

    public PasteCommand(TextEditor editor) {
        this.editor = editor;
        this.previousContent = editor.clipboard; // 记录当前剪贴板内容以便撤销
    }

    @Override
    public void execute() {
        editor.paste();
    }

    @Override
    public void undo() {
        editor.copy(previousContent); // 恢复到执行前的状态
    }
}

2.3 定义命令发出者

// 调用者类 - 负责触发命令的执行
class EditorInvoker {
    private Command command;

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

    public void pressButton() {
        if (command != null) {
            command.execute();
        }
    }

    public void undo() {
        if (command != null) {
            command.undo();
        }
    }
}

2.4 测试程序

// 测试命令模式的应用
public class CommandPatternDemo {
    public static void main(String[] args) {
        TextEditor editor = new TextEditor();
        EditorInvoker invoker = new EditorInvoker();

        // 设置并执行复制命令
        invoker.setCommand(new CopyCommand(editor, "Hello World"));
        invoker.pressButton();  

        // 设置并执行粘贴命令
        invoker.setCommand(new PasteCommand(editor));
        invoker.pressButton();  

        // 撤销上一步操作(即撤销粘贴)
        invoker.undo();       

        // 再次尝试粘贴,应该显示剪贴板为空的信息
        invoker.pressButton();  
        
        // 撤销上一步操作(即撤销复制)
        invoker.undo();  
    }
}

输出结果

Copying text: Hello World
Pasting text: Hello World
Copying text: Hello World
Clipboard is empty, nothing to paste.
Clearing clipboard.

这段代码展示了如何利用命令模式将不同的编辑操作封装为独立的对象(命令)。每个命令对象都实现了Command接口,并且可以被调用者统一管理。通过这种方式,我们可以轻松地添加新的命令类型,而不会影响已有的代码结构。此外,命令模式还使得我们能够方便地实现撤销功能,只需让每个命令记住足够的信息来恢复其执行之前的状态即可。


文章同步更新在个人微信公众号:IT路旅记
感兴趣的伙伴可以关注订阅,方便浏览。

标签:void,模式,命令,clipboard,editor,撤销,设计模式,public
From: https://blog.csdn.net/qq_39144436/article/details/145124285

相关文章

  • OpenWrt小白常用命令大全
    https://www.fnmqs.work/archives/63/硬件相关cat/proc/cpuinfo#查看CPU信息uname-m#查看CPU架构cat/proc/meminfo#查看内存使用情况df-h#查看磁盘的使用率系统相关uname-a#查看内核信息opkgprint-architecture#可接受的架构dmesg#读取内核的日志l......
  • 设计模式:策略模式——行为型模式
    目录主要组成优点缺点使用场景:示例代码普通写法:策略模式:策略模式与if-else的关系: 区别总结策略模式(StrategyPattern)是一种行为型设计模式,旨在通过定义一系列的算法(或策略),将每个算法封装起来,使它们可以互换,并使得算法的变化独立于使用算法的客户端。主要组成......
  • [TypeScript] 实现一个强大的模式匹配
    前言众所不周知,在Rust语言中,有一个强大的语法,模式匹配:fnmain(){letdata=Some(12);matchdata{Some(i)=>println!("{}",i),None=>println!("Nodata"),}}那么在typescript中我们如何为自己实现一个这么好用的语法呢?match.ts//......
  • 详解Redis的Set类型及相关命令
    目录SADDSMEMEBERSSISMEMBERSCARDSPOPSMOVESREMSINTERSINTERSTORESUNIONSUNIONSTORESDIFFSDIFFSTORE内部编码应用场景集合类型是保存多个字符串类型的元素的,但和列表类型不同的是,集合中元素之间是⽆序的,且元素不允许重复。⼀个集合中最多可以存储个元素。......
  • 单例模式(Singleton Pattern)——游戏开发常用设计模式(一)
    前言单例模式应该是在unity游戏开发中最简单最常用的设计模式之一,无论是管理全局游戏状态、处理资源加载,还是控制音频播放,单例模式都能为我们提供一个简洁的解决方案——确保一个类只有一个实例,并允许在游戏的任何地方轻松访问它。然而,这种便利性也伴随着潜在的风险,比如代码耦合......
  • C#中的设计模式:构建更加优雅的代码
    C#在面向对象编程(OOP)方面的强大支持,我们可以探讨“C#中的设计模式”。这不仅有助于理解如何更好地组织代码,还能提高代码的可维护性和可扩展性。引言设计模式是软件工程中经过实践验证的解决方案模板,它们提供了一种标准化的方法来解决常见的开发问题。对于使用C#进行开发......
  • 在 PowerShell 中,管理 Active Directory 域服务(AD DS)涉及到很多命令,这些命令可以根据
    在PowerShell中,管理ActiveDirectory域服务(ADDS)涉及到很多命令,这些命令可以根据不同的功能进行分类。下面是一个按功能分类的PowerShell命令表格,帮助你快速找到相关命令。功能分类命令描述域和信任管理Get-ADDomain获取当前域的配置信息。 Set-ADDomain......
  • Linux操作命令之网络管理
    一、网络基础命令1、查看网络信息[root@controller~]#ipaddrshow1:lo:<LOOPBACK,UP,LOWER_UP>mtu65536qdiscnoqueuestateUNKNOWNgroupdefaultqlen1000link/loopback00:00:00:00:00:00brd00:00:00:00:00:00inet127.0.0.1/8scopehostlo......
  • C语言:虚拟地址空间及编译模式
    所谓虚拟地址空间,就是程序可以使用的虚拟地址的有效范围。虚拟地址和物理地址的映射关系由操作系统决定,相应地,虚拟地址空间的大小也由操作系统决定,但还会受到编译模式的影响。这节我们先讲解CPU,再讲解编译模式,让大家了解编译器是如何配合CPU来提高程序运行速度的。CPU的......
  • fping命令详解
    fping是一个用于发送ICMPECHO_REQUEST数据包到网络主机的工具,类似于ping命令,但它可以同时ping多个主机。fping通常用于网络监控和批量测试主机的可达性。安装fping在大多数Linux发行版中,fping可以通过包管理器安装:Debian/Ubuntu:sudoapt-getinstallfpingCen......