zoukankan      html  css  js  c++  java
  • 【设计模式】命令模式

    1、 定义

    1.1    标准定义

      命令模式是一个高内聚的模式,其定义为:

      Encapsulate a request as an object,therebyletting you parameterize clients with different requests,queue or log requests,and support undoableoperations.(将一个请求封装成一个对象,从而让你使用不同的请求把客户端参数化,对请求排队或者记录请求日志,可以提供命令的撤销和恢复功能。)

    1.2 类图

      ● Receive接收者角色
      该角色就是干活的角色, 命令传递到这里是应该被执行的。

      ● Command命令角色
      需要执行的所有命令都在这里声明。

      ● Invoker调用者角色
      接收到命令, 并执行命令。

    2、实现

    2.1 类图

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

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

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

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

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

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

    2.2 代码

    2.2.1 command类

    // Command.h
    
    #ifndef _COMMAND_H_
    #define _COMMAND_H_
    
    class Command
    {
    public:
        virtual ~Command();
        virtual void Execute()=0;
    protected:
        Command();
    private:
    };
    
    class Receiver;
    
    class ConcreteCommand : public Command
    {
    public:
        ConcreteCommand(Receiver* pReceiver);
        ~ConcreteCommand();
        virtual void Execute();
    protected:
    private:
        Receiver* _recv;
    };
    
    class Invoker
    {
    public:
        Invoker(Command* pCommand);
        ~Invoker();
        void Invoke();
    protected:
    private:
        Command* _cmd;
    };
    
    class Receiver
    {
    public:
        Receiver();
        ~Receiver();
        void Action();
    protected:
    private:
    };
    
    #endif
    // Command.cpp
    
    #include "Command.h"
    #include <iostream>
    
    using namespace std;
    
    Command::Command(){}
    
    Command::~Command(){}
    
    ConcreteCommand::ConcreteCommand(Receiver* pReceiver)
    {
        this->_recv = pReceiver;
    }
    
    ConcreteCommand::~ConcreteCommand(){}
    
    void ConcreteCommand::Execute()
    {
        this->_recv->Action();
    }
    
    Receiver::Receiver(){}
    
    Receiver::~Receiver(){}
    
    void Receiver::Action()
    {
        cout << "Receiver::Action" << endl;
    }
    
    Invoker::Invoker(Command* pCommand)
    {
        this->_cmd = pCommand;
    }
    
    Invoker::~Invoker(){}
    
    void Invoker::Invoke()
    {
        this->_cmd->Execute();
    }

    2.2.2 调用

    // main.cpp
    
    #include "Command.h"
    
    int main()
    {
        //创建具体命令对象pCmd并设定它的接收者pRev
        Receiver* pRev = new Receiver();
        Command* pCmd = new ConcreteCommand(pRev);
        //请求绑定命令
        Invoker* pInv = new Invoker(pCmd);
        pInv->Invoke();
    
        return 0;
    }

    3、优缺点

    3.1 优点

      ● 类间解耦
      调用者角色与接收者角色之间没有任何依赖关系, 调用者实现功能时只需调用Command抽象类的execute方法就可以, 不需要了解到底是哪个接收者执行。

      ● 可扩展性
      Command的子类可以非常容易地扩展, 而调用者Invoker和高层次的模块Client不产生严重的代码耦合。

      ● 命令模式结合其他模式会更优秀
      命令模式可以结合责任链模式, 实现命令族解析任务; 结合模板方法模式, 则可以减少Command子类的膨胀问题。

      ● 可操作性
      允许接收请求的一方决定是否要否决请求;可以容易地实现对请求的撤销和重做。

    3.2 缺点

      命令模式也是有缺点的,请看Command的子类:如果有N个命令,问题就出来了,Command的子类就可不是几个,而是N个,这个类膨胀得非常大,这个就需要在项目中慎重考虑使用。

  • 相关阅读:
    【Python开发】python使用urllib2抓取防爬取链接
    【Python开发】python使用urllib2抓取防爬取链接
    【Python开发】Python之re模块 —— 正则表达式操作
    【Python开发】Python之re模块 —— 正则表达式操作
    【Python开发】Url中文字符时记得转码edcode("utf-8")
    【Python开发】Url中文字符时记得转码edcode("utf-8")
    【Python开发】urllib2异常处理
    【Python开发】urllib2异常处理
    【Python开发】urllib2.urlopen超时问题
    【Python开发】urllib2.urlopen超时问题
  • 原文地址:https://www.cnblogs.com/ChinaHook/p/7247717.html
Copyright © 2011-2022 走看看