当前位置:首页 > 科技  > 软件

命令模式:将请求封装为对象

来源: 责编: 时间:2023-10-24 09:00:26 445观看
导读欢迎来到设计模式系列的第十五篇文章!今天,我们将深入研究命令模式。命令模式是一种行为型设计模式,它允许您将请求封装成对象,从而允许您根据不同的请求、队列或者日志来参数化其他对象,并支持可撤销的操作。什么是命令模

欢迎来到设计模式系列的第十五篇文章!今天,我们将深入研究命令模式。命令模式是一种行为型设计模式,它允许您将请求封装成对象,从而允许您根据不同的请求、队列或者日志来参数化其他对象,并支持可撤销的操作。Mbi28资讯网——每日最新资讯28at.com

什么是命令模式?

命令模式是一种行为型设计模式,它将请求或操作封装成独立的命令对象。这些命令对象包括了执行操作所需的所有信息,例如操作方法、参数和接收者。Mbi28资讯网——每日最新资讯28at.com

命令模式允许您将命令发送者(客户端)和命令执行者(接收者)解耦,使得发送者无需知道接收者的具体类别。Mbi28资讯网——每日最新资讯28at.com

在命令模式中,通常包含以下关键角色:Mbi28资讯网——每日最新资讯28at.com

  1. 命令(Command):声明了执行操作的接口,通常包括一个 execute 方法。
  2. 具体命令(Concrete Command):实现了命令接口,包含了实际的操作逻辑。每个具体命令对象都与一个接收者相关联。
  3. 接收者(Receiver):执行命令实际操作的对象。
  4. 调用者(Invoker):负责调用命令对象来执行请求。
  5. 客户端(Client):创建命令对象并设置其接收者,然后将命令对象传递给调用者。

为什么需要命令模式?

命令模式有以下几个优点:Mbi28资讯网——每日最新资讯28at.com

  1. 解耦:命令模式可以将发送者和接收者解耦,发送者无需知道接收者的具体实现,从而提高了系统的灵活性。
  2. 可扩展性:您可以轻松地添加新的命令类,而无需修改已有的代码。
  3. 撤销操作:命令对象通常会保存操作的状态,从而支持撤销操作。
  4. 日志记录和事务管理:您可以使用命令模式来记录所有执行的命令,以便进行事务管理或撤销。

命令模式的实现

让我们通过一个简单的示例来演示命令模式的实现。假设我们正在构建一个遥控器应用,用户可以通过遥控器执行不同的操作,例如打开电视、切换频道和调整音量。Mbi28资讯网——每日最新资讯28at.com

首先,我们定义一个命令接口 Command,它包括了一个 execute 方法:Mbi28资讯网——每日最新资讯28at.com

public interface Command {    void execute();}

接下来,我们创建具体的命令类,例如 TurnOnCommand、ChangeChannelCommand 和 AdjustVolumeCommand,它们实现了 Command 接口,并分别执行相应的操作。Mbi28资讯网——每日最新资讯28at.com

public class TurnOnCommand implements Command {    private Television television;    public TurnOnCommand(Television television) {        this.television = television;    }    public void execute() {        television.turnOn();    }}// 类似地实现 ChangeChannelCommand 和 AdjustVolumeCommand

然后,我们创建接收者类 Television,它包含了实际的操作逻辑:Mbi28资讯网——每日最新资讯28at.com

public class Television {    public void turnOn() {        System.out.println("电视已打开");    }    public void changeChannel() {        System.out.println("切换频道");    }    public void adjustVolume() {        System.out.println("调整音量");    }}

最后,我们创建调用者类 RemoteControl,它接收并执行命令:Mbi28资讯网——每日最新资讯28at.com

public class RemoteControl {    private Command command;    public void setCommand(Command command) {        this.command = command;    }    public void pressButton() {        command.execute();    }}

客户端代码如下:Mbi28资讯网——每日最新资讯28at.com

public class Client {    public static void main(String[] args) {        Television television = new Television();        Command turnOnCommand = new TurnOnCommand(television);        Command changeChannelCommand = new ChangeChannelCommand(television);        Command adjustVolumeCommand = new AdjustVolumeCommand(television);        RemoteControl remoteControl = new RemoteControl();        remoteControl.setCommand(turnOnCommand);        remoteControl.pressButton();        remoteControl.setCommand(changeChannelCommand);        remoteControl.pressButton();        remoteControl.setCommand(adjustVolumeCommand);        remoteControl.pressButton();    }}

这个示例中,我们将不同的操作(打开电视、切换频道、调整音量)封装成了命令对象,通过遥控器执行这些命令,而不需要直接调用接收者的方法。Mbi28资讯网——每日最新资讯28at.com

宏命令

宏命令是一种命令模式的扩展,它允许您将多个命令组合成一个更大的命令。宏命令本身也是一个命令,可以执行一系列子命令。这对于执行复杂的操作或者创建多级撤销机制非常有用。Mbi28资讯网——每日最新资讯28at.com

让我们通过一个示例来了解宏命令。假设我们有一个文本编辑器,需要实现一个宏命令来执行以下操作:Mbi28资讯网——每日最新资讯28at.com

  1. 打开文件
  2. 编辑文件
  3. 保存文件

首先,我们定义一个宏命令接口 MacroCommand,它包含了 add 和 execute 方法:Mbi28资讯网——每日最新资讯28at.com

public interface MacroCommand {    void add(Command command);    void execute();}

接下来,我们创建一个具体的宏命令类 TextEditorMacro,它可以添加和执行多个子命令:Mbi28资讯网——每日最新资讯28at.com

public class TextEditorMacro implements MacroCommand {    private List<Command> commands = new ArrayList<>();    public void add(Command command) {        commands.add(command);    }    public void execute() {        for (Command command : commands) {            command.execute();        }    }}

然后,我们可以创建多个子命令,例如 OpenFileCommand、EditFileCommand 和 SaveFileCommand,它们分别执行打开、编辑和保存文件的操作。Mbi28资讯网——每日最新资讯28at.com

最后,我们可以使用宏命令将这些子命令组合成一个宏命令:Mbi28资讯网——每日最新资讯28at.com

public class Client {    public static void main(String[] args) {        OpenFileCommand openFile = new OpenFileCommand();        EditFileCommand editFile = new EditFileCommand();        SaveFileCommand saveFile = new SaveFileCommand();        TextEditorMacro macro = new TextEditorMacro();        macro.add(openFile);        macro.add(editFile);        macro.add(saveFile);        // 执行宏命令,依次执行子命令        macro.execute();    }}

这样,我们就实现了一个宏命令,可以一次性执行多个子命令,从而打开、编辑和保存文件。Mbi28资讯网——每日最新资讯28at.com

撤销和重做

命令模式还支持撤销和重做操作。Mbi28资讯网——每日最新资讯28at.com

为了实现撤销,我们需要在命令对象中保存执行前的状态,并提供一个 undo 方法来恢复到之前的状态。Mbi28资讯网——每日最新资讯28at.com

让我们通过一个简单的示例来演示撤销和重做。假设我们有一个文本编辑器,可以执行添加文本、删除文本和撤销操作。Mbi28资讯网——每日最新资讯28at.com

首先,我们定义一个命令接口 Command,包括了 execute 和 undo 方法:Mbi28资讯网——每日最新资讯28at.com

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

接下来,我们创建具体的命令类,例如 AddTextCommand 和 DeleteTextCommand,它们分别执行添加文本和删除文本的操作,并实现了 undo 方法来撤销操作。Mbi28资讯网——每日最新资讯28at.com

public class AddTextCommand implements Command {    private TextEditor textEditor;    private String addedText;    public AddTextCommand(TextEditor textEditor, String addedText) {        this.textEditor = textEditor;        this.addedText = addedText;    }    public void execute() {        textEditor.addText(addedText);    }    public void undo() {        textEditor.deleteText(addedText);    }}// 类似地实现 DeleteTextCommand

然后,我们创建接收者类 TextEditor,它包含了实际的文本编辑逻辑,包括添加文本、删除文本和显示文本。Mbi28资讯网——每日最新资讯28at.com

public class TextEditor {    private StringBuilder text = new StringBuilder();    public void addText(String addedText) {        text.append(addedText);    }    public void deleteText(String deletedText) {        int start = text.lastIndexOf(deletedText);        if (start != -1) {            text.delete(start, start + deletedText.length());        }    }    public void displayText() {        System.out.println(text.toString());    }}

最后,我们可以创建一个客户端来测试撤销和重做操作:Mbi28资讯网——每日最新资讯28at.com

public class Client {    public static void main(String[] args) {        TextEditor textEditor = new TextEditor();        Command addCommand1 = new AddTextCommand(textEditor, "Hello, ");        Command addCommand2 = new AddTextCommand(textEditor, "Design Patterns!");        Command deleteCommand = new DeleteTextCommand(textEditor, "Patterns!");        // 执行添加和删除操作        addCommand1.execute();        addCommand2.execute();        deleteCommand.execute();        // 显示当前文本        textEditor.displayText(); // 输出: Hello, Design!        // 撤销删除操作        deleteCommand.undo();        // 显示当前文本        textEditor.displayText(); // 输出: Hello, Design Patterns!    }}

通过上述代码,我们实现了撤销和重做操作,可以在执行操作后撤销到之前的状态,然后再重做。这在需要保留操作历史的应用程序中非常有用。Mbi28资讯网——每日最新资讯28at.com

总结

命令模式是一种行为型设计模式,它将请求和操作解耦,允许将操作封装成独立的命令对象。这使得我们能够实现撤销、重做、宏命令等高级功能,并且更容易扩展新的命令。Mbi28资讯网——每日最新资讯28at.com

在设计软件系统时,考虑使用命令模式来提高代码的可维护性和灵活性,特别是需要支持撤销和重做功能的应用程序。Mbi28资讯网——每日最新资讯28at.com

本文链接:http://www.28at.com/showinfo-26-14724-0.html命令模式:将请求封装为对象

声明:本网页内容旨在传播知识,若有侵权等问题请及时与本网联系,我们将在第一时间删除处理。邮件:2376512515@qq.com

上一篇: Go中使用sync.Map实现线程安全的缓存

下一篇: 让图片完美适应:掌握 CSS 的 Object-Fit 与 Object-Position

标签:
  • 热门焦点
  • Find N3入网:最高支持16+1TB

    OPPO将于近期登场的Find N3折叠屏目前已经正式入网,型号为PHN110。本次Find N3在外观方面相比前两代有很大的变化,不再是小号的横向折叠屏,而是跟别的厂商一样采用了较为常见的
  • 消息称迪士尼要拍真人版《魔发奇缘》:女主可能也找黑人演员

    8月5日消息,迪士尼确实有点忙,忙着将不少动画改成真人版,继《美人鱼》后,真人版《白雪公主》、《魔发奇缘》也在路上了。据外媒消息称,迪士尼将打造真人版
  • Rust中的高吞吐量流处理

    作者 | Noz编译 | 王瑞平本篇文章主要介绍了Rust中流处理的概念、方法和优化。作者不仅介绍了流处理的基本概念以及Rust中常用的流处理库,还使用这些库实现了一个流处理程序
  • 多线程开发带来的问题与解决方法

    使用多线程主要会带来以下几个问题:(一)线程安全问题  线程安全问题指的是在某一线程从开始访问到结束访问某一数据期间,该数据被其他的线程所修改,那么对于当前线程而言,该线程
  • 19个 JavaScript 单行代码技巧,让你看起来像个专业人士

    今天这篇文章跟大家分享18个JS单行代码,你只需花几分钟时间,即可帮助您了解一些您可能不知道的 JS 知识,如果您已经知道了,就当作复习一下,古人云,温故而知新嘛。现在,我们就开始今
  • 猿辅导与新东方的两种“归途”

    作者|卓心月 出品|零态LT(ID:LingTai_LT)如何成为一家伟大企业?答案一定是对&ldquo;势&rdquo;的把握,这其中最关键的当属对企业战略的制定,且能够站在未来看现在,即使这其中的
  • 8月见!小米MIX Fold 3获得3C认证:支持67W快充

    这段时间以来,包括三星、一加、荣耀等等有不少品牌旗下的最新折叠屏旗舰都得到了不少爆料,而小米新一代折叠屏旗舰——小米MIX Fold 3此前也屡屡被传
  • 华为Mate60标准版细节曝光:经典星环相机模组回归

    这段时间以来,关于华为新旗舰的爆料日渐密集。据此前多方爆料,今年华为将开始恢复一年双旗舰战略,除上半年推出的P60系列外,往年下半年的Mate系列也将
  • 三星Galaxy Z Fold5官方渲染图曝光:13.4mm折叠厚度依旧感人

    据官方此前宣布,三星将于7月26日在韩国首尔举办Unpacked活动,届时将带来带来包括Galaxy Buds 3、Galaxy Watch 6、Galaxy Tab S9、Galaxy Z Flip 5、
Top