• 行为型-命令模式


    一、简介:

    命令模式(Command Pattern)是一种行为型设计模式,它的主要目的是将一个请求或操作封装成一个对象,从而允许你参数化客户端对象,并以不同的请求来进行操作和排队请求。命令模式将请求的发送者(调用者)和接收者(执行者)解耦,同时允许你支持撤销操作和事务。

    以下是命令模式的关键参与者和工作原理:

    1. 命令(Command):命令是一个抽象类或接口,它定义了执行特定操作的方法(通常称为execute),以及可能需要的参数。具体的命令类将实现这个接口,并提供具体的操作和参数。

    2. 具体命令(Concrete Command):具体命令是命令接口的实现,它包含了实际执行操作的代码,以及操作需要的参数。

    3. 调用者(Invoker):调用者是发送命令的对象,它包含了一个命令对象,并在需要时触发命令的执行。调用者不需要知道命令的具体实现,只需要知道如何触发命令执行。

    4. 接收者(Receiver):接收者是实际执行命令操作的对象。命令对象会将操作委托给接收者来执行。接收者知道如何执行命令的具体操作。

    5. 客户端(Client)客户端创建具体命令对象,并将命令对象传递给调用者。客户端也可以负责设置命令的参数。

    命令模式的工作原理如下:

    • 客户端创建一个具体命令对象,并指定它要执行的操作和参数。
    • 将具体命令对象传递给调用者对象。
    • 调用者对象在需要时触发具体命令对象的执行方法(execute)。
    • 具体命令对象执行操作,并委托给接收者来完成。

    命令模式的优点包括:

    1. 松耦合:命令模式将调用者和接收者解耦,使得它们不需要相互了解具体的实现细节,从而提高了系统的松耦合度。

    2. 可扩展性:可以轻松地添加新的命令类和接收者类,而无需修改现有的代码。

    3. 撤销操作:命令模式支持撤销操作,因为可以把一系列命令对象加入栈中,从而允许逆向操作。

    4. 事务支持:可以将多个命令组合成一个事务,以确保它们要么全部成功执行,要么全部失败。

    命令模式常见的应用场景包括遥控器控制、队列任务处理、文本编辑器的撤销/恢复功能等需要将请求封装成对象并支持撤销操作的情况。

    二、示例:

    以下示例中,我们创建了两个具体命令类来执行添加文本和删除文本操作,每个具体命令类都支持executeundo操作。命令管理器用于执行命令并支持撤销操作。通过撤销操作,用户可以回退到之前的编辑状态,实现了命令模式的撤销功能。

    1. using System;
    2. using System.Collections.Generic;
    3. // 命令接口
    4. interface ICommand
    5. {
    6. void Execute();
    7. void Undo();
    8. }
    9. // 具体命令类 - 添加文本
    10. class AddTextCommand : ICommand
    11. {
    12. private readonly TextEditor textEditor;
    13. private readonly string textToAdd;
    14. public AddTextCommand(TextEditor editor, string text)
    15. {
    16. textEditor = editor;
    17. textToAdd = text;
    18. }
    19. public void Execute()
    20. {
    21. textEditor.AddText(textToAdd);
    22. }
    23. public void Undo()
    24. {
    25. textEditor.DeleteText(textEditor.Text.Length - textToAdd.Length, textToAdd.Length);
    26. }
    27. }
    28. // 具体命令类 - 删除文本
    29. class DeleteTextCommand : ICommand
    30. {
    31. private readonly TextEditor textEditor;
    32. private readonly int position;
    33. private readonly string deletedText;
    34. public DeleteTextCommand(TextEditor editor, int pos, int length)
    35. {
    36. textEditor = editor;
    37. position = pos;
    38. deletedText = textEditor.Text.Substring(pos, length);
    39. }
    40. public void Execute()
    41. {
    42. textEditor.DeleteText(position, deletedText.Length);
    43. }
    44. public void Undo()
    45. {
    46. textEditor.InsertText(position, deletedText);
    47. }
    48. }
    49. // 接收者 - 文本编辑器
    50. class TextEditor
    51. {
    52. public string Text { get; private set; } = "";
    53. public void AddText(string text)
    54. {
    55. Text += text;
    56. }
    57. public void DeleteText(int position, int length)
    58. {
    59. Text = Text.Remove(position, length);
    60. }
    61. public void InsertText(int position, string text)
    62. {
    63. Text = Text.Insert(position, text);
    64. }
    65. }
    66. // 命令管理器
    67. class CommandManager
    68. {
    69. private readonly Stack history = new Stack();
    70. public void Execute(ICommand command)
    71. {
    72. command.Execute();
    73. history.Push(command);
    74. }
    75. public void Undo()
    76. {
    77. if (history.Count > 0)
    78. {
    79. ICommand command = history.Pop();
    80. command.Undo();
    81. }
    82. }
    83. }
    84. class Program
    85. {
    86. static void Main()
    87. {
    88. TextEditor editor = new TextEditor();
    89. CommandManager commandManager = new CommandManager();
    90. // 添加文本
    91. ICommand addCommand1 = new AddTextCommand(editor, "Hello, ");
    92. commandManager.Execute(addCommand1);
    93. Console.WriteLine(editor.Text); // 输出:Hello,
    94. // 再次添加文本
    95. ICommand addCommand2 = new AddTextCommand(editor, "World!");
    96. commandManager.Execute(addCommand2);
    97. Console.WriteLine(editor.Text); // 输出:Hello, World!
    98. // 撤销操作
    99. commandManager.Undo();
    100. Console.WriteLine(editor.Text); // 输出:Hello,
    101. // 再次撤销操作
    102. commandManager.Undo();
    103. Console.WriteLine(editor.Text); // 输出:(空)
    104. }
    105. }

  • 相关阅读:
    html 标签
    【c++】运算符重载实例
    SQL改写系列九:外连接转内连接的常见场景与错误
    xp 系统 安装 python 2.7 ide pip
    【Svelte】-(7)绑定|Each 块绑定 / audio video 媒体标签绑定 / client offset 尺寸绑定 / this / 组件绑定
    排序算法——稳定性及其汇总
    漏洞分析:MS14-058(CVE-2014-4113)
    一、kafka基本原理
    【Golang】gin客户端动态加载Html格式文件
    《机器学习分类器 二》——朴素的贝叶斯算法,项目实践,算法实践。
  • 原文地址:https://blog.csdn.net/sindyra/article/details/133050243