zoukankan      html  css  js  c++  java
  • C++设计模式-Command命令模式

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

    由于“行为请求者”与“行为实现者”的紧耦合,使用命令模式,可以对请求排队或记录请求日志,以及支持可撤销的操作。

    UML图:


    Command类,用来声明执行操作的接口

    ConcreteCommand,将一个接收者对象绑定于一个操作,调用接收者相应的操作,以实现Execute

    Invoker类,要求该命令执行这个请求

    Receiver类,知道如何实施与执行一个与请求相关的操作,任何类都可能作为一个接收者。

    Command模式通过将请求封装到一个对象Command中,并将请求的接收者存放到具体的ConcreteCommand类中,从而实现调用操作的对象和操作的具体实现者之间的解耦。

    Command模式结构图中,将请求的接收者(处理者)放到Command的具体子类ConcreteCommand中,当请求到来时(Invoker发出Invoke消息激活Command对象),ConcreteCommand将处理请求交给Receiver对象进行处理。

    命令模式的优点:
    1,它能较容易地设计一个命令队列;
    2,在需要的情况下,可以较容易地将命令记入日志;
    3,允许接收请求的一方决定是否要否决请求。
    4,可以容易地实现对请求的撤销和重做;
    5,由于加进新的具体命令类不影响其他的类,因此增加新的具体命令类很容易。

    命令模式把请求一个操作的对象与知道怎么执行一个操作的对象分割开。

    Command模式关键就是讲一个请求封装到一个类中(Command),再提供处理对象(Receiver),最后Command命令由Invoker激活。另外,我们可以将请求接收者的处理抽象出来作为参数传给Command对象,实际也就是回调的机制来实现这一点。也就是讲处理操作方法地址通过参数传递给Command对象,Command对象在适当的时候再调用该函数。

    Command模式将调用操作的对象和知道如何实现该操作的对象解耦,在上面Command的结构图中,Invoker对象根本就不知道具体的是哪个对象在处理Execute操作(当然要知道是Command类别的对象)。
    在Command要增加新的处理操作对象很容易,我们可以通过创建新的继承自Command的子类来实现这一点。
    Command模式可以和Memento模式结合起来,支持取消的操作。

    代码如下:

    Command.h

     1 #ifndef _COMMAND_H_
     2 #define _COMMAND_H_
     3 
     4 class Command
     5 {
     6 public:
     7     virtual ~Command();
     8     virtual void Execute()=0;
     9 protected:
    10     Command();
    11 private:
    12 };
    13 
    14 class Receiver;
    15 
    16 class ConcreteCommand : public Command
    17 {
    18 public:
    19     ConcreteCommand(Receiver* pReceiver);
    20     ~ConcreteCommand();
    21     virtual void Execute();
    22 protected:
    23 private:
    24     Receiver* _recv;
    25 };
    26 
    27 class Invoker
    28 {
    29 public:
    30     Invoker(Command* pCommand);
    31     ~Invoker();
    32     void Invoke();
    33 protected:
    34 private:
    35     Command* _cmd;
    36 };
    37 
    38 class Receiver
    39 {
    40 public:
    41     Receiver();
    42     ~Receiver();
    43     void Action();
    44 protected:
    45 private:
    46 };
    47 #endif

    Command.cpp

     1 #include "Command.h"
     2 #include <iostream>
     3 
     4 using namespace std;
     5 
     6 Command::Command()
     7 {}
     8 
     9 Command::~Command()
    10 {}
    11 
    12 ConcreteCommand::ConcreteCommand(Receiver* pReceiver)
    13 {
    14     this->_recv = pReceiver;
    15 }
    16 
    17 ConcreteCommand::~ConcreteCommand()
    18 {}
    19 
    20 void ConcreteCommand::Execute()
    21 {
    22     this->_recv->Action();
    23 }
    24 
    25 Receiver::Receiver()
    26 {}
    27 
    28 Receiver::~Receiver()
    29 {}
    30 
    31 void Receiver::Action()
    32 {
    33     cout << "Receiver::Action" << endl;
    34 }
    35 
    36 Invoker::Invoker(Command* pCommand)
    37 {
    38     this->_cmd = pCommand;
    39 }
    40 
    41 Invoker::~Invoker()
    42 {}
    43 
    44 void Invoker::Invoke()
    45 {
    46     this->_cmd->Execute();
    47 }

    main.cpp

     1 #include "Command.h"
     2 
     3 int main()
     4 {
     5     //创建具体命令对象pCmd并设定它的接收者pRev
     6     Receiver* pRev = new Receiver();
     7     Command* pCmd = new ConcreteCommand(pRev);
     8     //请求绑定命令
     9     Invoker* pInv = new Invoker(pCmd);
    10     pInv->Invoke();
    11 
    12     return 0;
    13 }
  • 相关阅读:
    CSS:清除浮动小技巧
    CSS:可见格式化模型BFC与应用
    JavaScript:所有视图属性和方法(innerWidth、outerHeight、clientX等)
    JavaScript:正则表达式(入门篇)
    JavaScript:六种继承比较
    表格内展示2行,超出部分省略
    Docker删除大量停止的container
    docker学习笔记
    使用redis实现分布式锁
    Sublime text 3 如何格式化HTML/css/js代码
  • 原文地址:https://www.cnblogs.com/jiese/p/3190414.html
Copyright © 2011-2022 走看看