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

 #ifndef _COMMAND_H_
#define _COMMAND_H_ class Command
{
public:
virtual ~Command();
virtual void Execute()=;
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();
}

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 ;
}

C++设计模式-Command命令模式的更多相关文章

  1. [C++设计模式] command 命令模式

    在软件系统中,"行为请求者"与"行为实现者"通常呈现一种"紧耦合". 但在某些场合,比方要对行为进行"记录.撤销/重做.事务&qu ...

  2. 设计模式 ( 十三 ) 命令模式Command(对象行为型)

    设计模式 ( 十三 ) 命令模式Command(对象行为型) 1.概述         在软件设计中,我们经常需要向某些对象发送请求,但是并不知道请求的接收者是谁,也不知道被请求的操作是哪个,我们只需 ...

  3. 乐在其中设计模式(C#) - 命令模式(Command Pattern)

    原文:乐在其中设计模式(C#) - 命令模式(Command Pattern) [索引页][源码下载] 乐在其中设计模式(C#) - 命令模式(Command Pattern) 作者:webabcd ...

  4. 面向对象设计模式_命令模式(Command)解读

    在.Net框架中很多对象的方法中都会有Invoke方法,这种方法的设计实际是用了设计模式的命令模式, 模式图如下 其核心思路是将Client 向Receiver发送的命令行为进行抽象(ICommand ...

  5. 设计模式14:Command 命令模式(行为型模式)

    Command 命令模式(行为型模式) 耦合与变化 耦合是软件不能抵御变化的根本性原因.不仅实体对象与实体对象之间存在耦合关系,实体对象与行为操作之间也存在耦合关系. 动机(Motivation) 在 ...

  6. 设计模式之命令模式(Command)摘录

    23种GOF设计模式一般分为三大类:创建型模式.结构型模式.行为模式. 创建型模式抽象了实例化过程,它们帮助一个系统独立于怎样创建.组合和表示它的那些对象.一个类创建型模式使用继承改变被实例化的类,而 ...

  7. 折腾Java设计模式之命令模式

    博客原文地址 折腾Java设计模式之命令模式 命令模式 wiki上的描述 Encapsulate a request as an object, thereby allowing for the pa ...

  8. 22、Command 命令模式

    1.command 命令模式 命令模式(Command Pattern):在软件设计中,我们经常需要向某些对象发送请求,但是并不知道请求的接收者是谁,也不知道被请求的操作是哪个,我们只需在程序运行时指 ...

  9. python设计模式之命令模式

    python设计模式之命令模式 现在多数应用都有撤销操作.虽然难以想象,但在很多年里,任何软件中确实都不存在撤销操作.撤销操作是在1974年引入的,但Fortran和Lisp分别早在1957年和195 ...

随机推荐

  1. dedecms 后台发布后的文章不能编辑出现一片空白的解决办法

    dede后台无法写新文章也无法编辑以前的文档,文章编辑的地方无法写入,出现无法显示该页面的问题,这是怎么回事?我的dede在ftp中换过文件夹,是不是跟这个有关?该如何解决这个问题? 以下修改是针对d ...

  2. ”未在本地计算机上注册“microsoft.et.OLEDB.4.0”提供程序。“解决方案大集合

    本人在做一个连接Access数据库的时候,程序扔给我一个如此Bug——“未在本地计算机上注册“microsoft.et.OLEDB.4.0”, 请教度娘,告诉我可能是如下因素: 一.“设置应用程序池默 ...

  3. Android深度探索HAL与驱动开发 第三章 Git入门

    Git功能十分复杂,简单来说它使你的开发更为快捷和可控,尤其是在开源项目上展现的友好的交互和回馈. 熟悉一些git指令操作对开发者的帮助可以避免开发者受到一些外在因素打断开发进度,甚至延误项目的che ...

  4. Enum.GetHashCode()的问题

    先说一下,正常如果代码可以定义成枚举,我是比较倾向于定义成枚举的,类似这样: public enum Gender { /// <summary> /// 男 /// </summa ...

  5. python ABC

    因为项目需要,总是会有各种各样要重命名文件的场合,manual的方法当然不可取,bat的方法又感觉不够强大,所以就从零开始学python,就为了能够自动批量修改文件名,倒腾了一个周六,总算可以了 :) ...

  6. 【HDU1960】Taxi Cab Scheme(最小路径覆盖)

    Taxi Cab Scheme Time Limit: 5000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)T ...

  7. .NET设计规范————命名规范

    NET设计规范:约定.惯用法与模式———命名规范 前言:          最近在看<.NET设计规范:约定.惯用法与模式>一书,主要还是讲.NET的设计规范,以前对这一块也不是特别在意, ...

  8. Head First设计模式之策略模式(Strategy Pattern)

    前言: 刚刚开始学习设计模式,之前也接触过一些,但是从来都没有系统的学过,这次打算好好的学习一下.这里就当是对学习过程的一个记录.整理,以便可以在以后不时的温故知新. 这一节采用一个鸭子的示例,层层推 ...

  9. vmware12无法打开内核设备“\\.\Global\vmx86”

    vmware12 无法打开内核设备"\\.\Global\vmx86": 系统找不到指定的文件.你想要在安装 VMware Workstation 前重启吗? 打开vmware12 ...

  10. navicat连接My SQL时忘记root密码处理方法

    前端时间安装完My SQL5.6以后很长时间没用过,用navicat连接时有错误提示 应该是密码错误了,但是忘记了root的密码. 在网上找了很久,终于找到修改root密码的方法并修改成功. 1. 关 ...