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
#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命令模式的更多相关文章
- [C++设计模式] command 命令模式
在软件系统中,"行为请求者"与"行为实现者"通常呈现一种"紧耦合". 但在某些场合,比方要对行为进行"记录.撤销/重做.事务&qu ...
- 设计模式 ( 十三 ) 命令模式Command(对象行为型)
设计模式 ( 十三 ) 命令模式Command(对象行为型) 1.概述 在软件设计中,我们经常需要向某些对象发送请求,但是并不知道请求的接收者是谁,也不知道被请求的操作是哪个,我们只需 ...
- 乐在其中设计模式(C#) - 命令模式(Command Pattern)
原文:乐在其中设计模式(C#) - 命令模式(Command Pattern) [索引页][源码下载] 乐在其中设计模式(C#) - 命令模式(Command Pattern) 作者:webabcd ...
- 面向对象设计模式_命令模式(Command)解读
在.Net框架中很多对象的方法中都会有Invoke方法,这种方法的设计实际是用了设计模式的命令模式, 模式图如下 其核心思路是将Client 向Receiver发送的命令行为进行抽象(ICommand ...
- 设计模式14:Command 命令模式(行为型模式)
Command 命令模式(行为型模式) 耦合与变化 耦合是软件不能抵御变化的根本性原因.不仅实体对象与实体对象之间存在耦合关系,实体对象与行为操作之间也存在耦合关系. 动机(Motivation) 在 ...
- 设计模式之命令模式(Command)摘录
23种GOF设计模式一般分为三大类:创建型模式.结构型模式.行为模式. 创建型模式抽象了实例化过程,它们帮助一个系统独立于怎样创建.组合和表示它的那些对象.一个类创建型模式使用继承改变被实例化的类,而 ...
- 折腾Java设计模式之命令模式
博客原文地址 折腾Java设计模式之命令模式 命令模式 wiki上的描述 Encapsulate a request as an object, thereby allowing for the pa ...
- 22、Command 命令模式
1.command 命令模式 命令模式(Command Pattern):在软件设计中,我们经常需要向某些对象发送请求,但是并不知道请求的接收者是谁,也不知道被请求的操作是哪个,我们只需在程序运行时指 ...
- python设计模式之命令模式
python设计模式之命令模式 现在多数应用都有撤销操作.虽然难以想象,但在很多年里,任何软件中确实都不存在撤销操作.撤销操作是在1974年引入的,但Fortran和Lisp分别早在1957年和195 ...
随机推荐
- JavaScript的json和Array及Array数组的使用方法
1.关于json JSON(JavaScript Object Notation) 是一种轻量级的数据交换格式.它基于ECMAScript的一个子集.也可以称为数据集和数组类似,能够存数据! //Ar ...
- 数据解析(XML和JSON数据结构)
一 解析 二 XML数据结构 三 JSON 数据结构 一 解析 1 定义: 从事先规定好的格式中提取数据 解析的前提:提前约定好格式,数据提供方按照格式提供数据.数据获取方则按照 ...
- html基础二
空标签 <br>用于分行 <hr>在 HTML 页面中创建水平线 “ctrl+/”用于在代码输入时注释 注释掉的内容将不会在浏览器上显示 这样方便在代码输入提高可读性 方便 ...
- ST第二次作业,相关程序测试及测试用例
public static int findLast(int[]x,int y){ for(int i = x.length-1;i>0;i--){//i>=0 if(x[i] == y) ...
- 《C专家编程》第四章——令人震惊的事实:数组和指针并不相同
数组和指针是C语言里相当重要的两部分内容,也是新手程序员最容易搞混的两个地方,本章我们锁定指针与数组,探讨它们的异同点. 首先来看指针与数组在声明上的区别: int a[10]; int *p; 很明 ...
- Xcode LLDB Debug教程
开胃小菜--简单的断点调试 在xcode中打开一个app,在想要break的行号上单击,即可生成一个深色的箭头标识--断点.如下图,在viewDidLoad:中设置了断点. 运行app,等待...就可 ...
- 3、C#入门第3课
1.c#中一个解决方案 里面两个程序 怎么一个启动另一个? 我一个解决方案下,有两个工程,我想让A工程在适当时候,启动B工程,比如A中有个按钮,一点,B工程就启动了. System.Diagnosti ...
- LINQ 客户端生成自增列
var testQuery = (from item in TestInfo.GroupBy(t=>t.TestName) select new { TestCode = item.Min(g= ...
- web编程
展示层 html/css/javascript/jquery/jquery easyUI/ajax bootstrap web层 varnish/haproxy/squid----lvs/keepal ...
- 错误: 程序包com.sun.istack.internal不存在
eclipse下maven打包是出现如下错误: [ERROR] D:\code-old\daba_user_mvn\src\main\java\com\dada\transaction\service ...