• 设计模式 —— 命令模式


    “行为变化”模式

    在组件的构建过程中,组件行为的变化经常到导致组件本身剧烈的变化。“行为变化”模式将组件的行为和组件本身进行解耦,从而支持组件行为的变化,实现两者之间的松耦合。
    典型模式:命令模式,访问器模式

    命令模式

    动机

    • 在软件构建过程,“行为请求者”与“行为实现者”通常呈现一种“紧耦合”。但是某些场合——比如需要对行为进行“记录、撤销、事物”等处理,这种无法抵御变化的紧耦合是不合适的。
    • 在这种情况下,如何将“行为请求者”与“行为实现者”解耦?将一组行为抽象为对象,可实现二者解耦。

    模式定义

    将一个请求(行为)封装为一个对象,从而使你可用不同的请求对客户进行参数化;对请求排队或记录请求日志,以及支持可撤销的操作。  —— 《设计模式》GOF

    UML结构

     

    代码示例

     1 #include <iostream>
     2 #include <vector>
     3 #include <string>
     4 using namespace std;
     6 
     7 class Command {
     8 public:
     9     virtual void execute() = 0;
    10 };
    11 
    12 class ConcreteCommand1 : public Command {
    13     string arg;
    14 public:
    15     ConcreteCommand1(const string & a) : arg(a) {}
    16     void execute() override {
    17         cout<< "#1 process..."<<arg<<endl;
    18     }
    19 };
    20 
    21 class ConcreteCommand2 : public Command {
    22     string arg;
    23 public:
    24     ConcreteCommand2(const string & a) : arg(a) {}
    25     void execute() override {
    26         cout<< "#2 process..."<<arg<<endl;
    27     }
    28 };
    29         
    30         
    31 class MacroCommand : public Command { 
    32     vector<Command*> commands;
    33 public:
    34     void addCommand(Command *c) { commands.push_back(c); }
    35     void execute() override {
    36         for (auto &c : commands) {
    37             c->execute();
    38         }
    39     }
    40 };
    41         
    42 int main() {
    43 
    44     ConcreteCommand1 command1(receiver, "Arg ###");
    45     ConcreteCommand2 command2(receiver, "Arg $$$");
    46     
    47     MacroCommand macro;
    48     macro.addCommand(&command1);
    49     macro.addCommand(&command2);
    50     
    51     macro.execute();
    52 
    53 }

    Command:声明执行操作的接口;
    ConcreteCommand:将一个接收者对象绑定于一个动作,之后,调用接收者相应的操作,以实现Execute来完成相应的命令;
    Client:创建一个具体命令对象,但是并没有设定它的接收者;
    Invoker:要求该命令执行这个请求;
    Receiver:知道如何实施与执行一个请求相关的操作,任何类都可能作为一个接收者。

    以上这些对象是按照下面的方式进行协作的:

    1. Client创建一个ConcreteCommand命令对象,并指定它的Receiver对象;
    2. Invoker对象存储该ConcreteCommand对象;
    3. 该Invoker通过调用Command对象的Execute操作来提交一个请求。如果这个命令请求是可以撤销的,ConcreteCommand就执行Execute操作之前存储当前状态以用于取消该命令请求;
    4. ConcreteCommand对象调用Receiver的一些操作以执行该请求。
     
    总结:
    • Cammand模式的根本目的在于将“行为请求者”与“行为实现者”解耦,在面向对象语言中,常见的手段“将行为抽象为对象”。
    • 实现Commmad接口的具体命令对象ConcreteCommand有时候根据需要可能会保存一些额外的状态信息。通过使用Composite模式,可以将多个命令封装为一个复合命令。
    • Command模式与C++中函数对象有些类似。但两者定义行为接口规范有所区别:Command以面向对象的“接口-实现”来定义行为接口规范,更严格,但有性能损失;C++函数对象以函数签名来定义接口规范,更灵活,性能更高。
  • 相关阅读:
    IE下全局对象报 脚本错误提示“对象不支持此属性或方法”解决方案
    IE6、7下inline-block不起作用
    IE下图片切换的时候,图片总是切换不成功---根本问题是IE缓存图片
    Fiddler 跟踪 手机页面数据包
    Regular Expression Matching——没理解的动态规划
    常见排序算法分析
    Flyweight模式(亨元模式)
    组合模式(Composite Pattern)
    装饰者模式(不太理解的设计模式)
    适配器模式
  • 原文地址:https://www.cnblogs.com/y4247464/p/15523305.html
Copyright © 2020-2023  润新知