Command Pattern -- 命令模式原理及实现(C++)
主要参考《大话设计模式》和《设计模式:可复用面向对象软件的基础》两本书。本文介绍命令模式的实现。
What it is:Encapsulate a request as an object, thereby letting you parameterize clients with different requests, queue or log requests, and support undoable operations.
将一个请求封装为一个对象,从而使你可用不同的请求对客户进行参数化;对请求排队或记录请求日志,以及支持可撤销的操作。在OOP中,一切都是对象,将请求封装成对象,符合OOP的设计思想,当将客户的单个请求封装成对象以后,我们就可以对这个请求存储更多的信息,使请求拥有更多的能力;命令模式同样能够把请求发送者和接收者解耦,使得命令发送者不用去关心请求将以何种方式被处理。
Command:声明执行操作的接口;
ConcreteCommand:将一个接收者对象绑定于一个动作,之后,调用接收者相应的操作,以实现Execute来完成相应的命令;
Client:创建一个具体命令对象,但是并没有设定它的接收者;
Invoker:要求该命令执行这个请求;
Receiver:知道如何实施与执行一个请求相关的操作,任何类都可能作为一个接收者。
以上这些对象是按照下面的方式进行协作的:
1.Client创建一个ConcreteCommand命令对象,并指定它的Receiver对象;
2.Invoker对象存储该ConcreteCommand对象;
3.该Invoker通过调用Command对象的Execute操作来提交一个请求。如果这个命令请求是可以撤销的,ConcreteCommand就执行Execute操作之前存储当前状态以用于取消该命令请求;
4.ConcreteCommand对象调用Receiver的一些操作以执行该请求。
具体事例:
我们去餐厅吃饭,我们是通过服务员来点菜,具体是谁来做这些菜和他们什么时候完成的这些菜,其实我们都不知道。抽象之,我们是“菜单请求者”,厨师是“菜单实现者”,2者之间是松耦合的,我们对这些菜的其他一些请求比如“撤销,重做”等,我们也不知道是谁在做。其实这就是本文要说的Command模式。将一个请求封装为一个对象,从而使你可用不同的请求对客户进行参数化;对请求排队或记录请求日志,以及支持可撤消的操作。[GOF 《设计模式》]
UML图如下:
具体代码C++代码实现:
#include <iostream>
#include <string>
#include <vector>
using namespace std; #define SAFE_DELETE(p) if (p) { delete p; p = NULL; }
/*烤肉师傅类,只负责烤串工作*/
class Barbecuer
{
public:
void BakeMutton(){cout<<"Bake mutton"<<endl;}
void BakeChickenWing(){cout<<"Bake ChickenWing"<<endl;}
}; /*抽象命令类:是执行具体操作的接口*/
class Command
{
public:
Command(){}
Command(Barbecuer *receiver):p_receiver(receiver){}
virtual void ExecuteCommand() = ; //执行命令
protected:
Barbecuer *p_receiver;
}; /*具体命令类:烤羊肉串命令*/
class BakeMuttonCommand:public Command
{
public:
BakeMuttonCommand(Barbecuer *receiver){p_receiver = receiver;}
void ExecuteCommand(){p_receiver->BakeMutton();}
}; /*具体命令类:烤鸡翅串命令*/
class BakeChickenWingCommand:public Command
{
public:
BakeChickenWingCommand(Barbecuer *receiver){p_receiver = receiver;}
void ExecuteCommand()
{p_receiver->BakeChickenWing();}
}; /*服务员类*/
class Waiter
{
public:
void SetOrder(Command *command);
void Notify();
private:
vector<Command *>p_commandList; //这里相当于一个命令对象队列
}; void Waiter::SetOrder(Command *command)
{
p_commandList.push_back(command);
cout << "增加烤肉命令" << endl;
} void Waiter::Notify()
{
vector<Command*>::iterator i;
for(i = p_commandList.begin(); i != p_commandList.end(); ++ i)
(*i)->ExecuteCommand();
} int main(int argc, char *argv[])
{
//生成烤肉师傅、服务员、订单对象
Barbecuer *p_cook = new Barbecuer();
Command *p_mutton = new BakeMuttonCommand(p_cook);
Command *p_chickenwing = new BakeChickenWingCommand(p_cook);
Waiter *p_waiter = new Waiter(); //将订单对象推送到命令队列
p_waiter->SetOrder(p_mutton);
p_waiter->SetOrder(p_chickenwing); //服务员通知烤肉师傅具体订单
p_waiter->Notify(); SAFE_DELETE(p_cook);
SAFE_DELETE(p_mutton);
SAFE_DELETE(p_chickenwing);
SAFE_DELETE(p_waiter); return ;
}
Command Pattern -- 命令模式原理及实现(C++)的更多相关文章
- Command Pattern 命令模式
定义: 命令模式将‘请求’封装成对象,以便使用不同的请求,队列或者日志来参数化其他对象,命令模式也支持可撤销的操作. 类图 如上图所示:Command类是用来声明执行操作的接口:ConcreteCom ...
- (Command Pattern)命令模式
定义 将“请求”封装成对象,以便使用不同的请求.队列或者日志来参数化其他对象.命令模式也支持可撤销的操作. 结构图: 命令模式的角色划分: Reciever(命令的接收者):接收命令,并知道如何进行必 ...
- [Design Pattern] Command Pattern 命令模式
发现公司的代码好像有用到 Command Pattern,回顾重温下. Command Pattern 的类图结构如下: 参考 <Head First Design Patterns(英文版)& ...
- Design Pattern - 命令模式
一般执行一个操作的过程, 创建对象, 并调用对象的函数, 函数执行, 返回 比如下面的类图, client直接调用Receiver.action 而命令模式, 抽象出command对象, 并在comm ...
- State Pattern -- 状态模式原理及实现(C++)
主要参考<大话设计模式>和<设计模式:可复用面向对象软件的基础>两本书.本文介绍命令模式的实现. 问题出发点 在实际开发中,我们经常会遇到这种情况:一个对象有多种状态,在每一个 ...
- c#设计模式系列:命令模式(Command Pattern)
引言 命令模式,我感觉"命令"就是任务,执行了命令就完成了一个任务.或者说,命令是任务,我们再从这个名字上并不知道命令的发出者和接受者分别是谁,为什么呢?因为我们并不关心他们是谁, ...
- 命令模式(Command)
命令模式(Command) 命令模式很好理解,举个例子,司令员下令让士兵去干件事情,从整个事情的角度来考虑,司令员的作用是,发出口令,口令经过传递,传到了士兵耳朵里,士兵去执行.这个过程好在,三者相互 ...
- Java设计模式の命令模式
意图: 将一个请求封装为一个对象,从而可用不同的请求对客户进行参数化:对请求排队或记录日志,以及支持可撤销的操作 动机: 将”发出请求的对象”和”接收与执行这些请求的对象”分隔开来. 效果: 1).c ...
- js命令模式
命令模式(Command),将一个请求封装为一个对象,从而使你可用不同的请求对客户进行参数化:对请求排队或记录请求日志,以及支持可撤销的操作. 从命令模式的结构图可以看出,它涉及到五个角色,它们分别是 ...
随机推荐
- asp.net的心得体会
1,gridview有点强大 2,页面的冗余代码有点多,性能略差. 3,access数据库的使用. 4,C/S端的开发,接触winform的开发 我自认为asp.net开发就像在一个别人限制好的画布上 ...
- nginx 做负载均衡
最近正在研究Nginx,Nginx作为反向代理服务器,可以对Web服务器提供加速,并且具有负载均衡的功能. 首先我要在官网下载Nginx(http://nginx.org/en/download.ht ...
- JavaScript吸顶灯的实现
吸顶灯是各站点常用的一个功能,它有两个特性 向下滚动到div位置时,该div一直固定在页面的顶部 向上滚动到div原有位置时,div又恢复到文档中的原位置 div可能是一个“分类菜单”,也可能是一个“ ...
- 关于点击空白关闭弹窗的js写法推荐
$(document).mouseup(function(e){ var _con = $(' 目标区域 '); // 设置目标区域 if(!_con.is(e.target) && ...
- Java 集合介绍
1, Set :集合中对象不按特定的方式排序,并且没有重复对象,它有些实现类能对集合按特定方式排序 List :集合中对象按照索引位置排序,可以有重复对象,允许按照对象在集合中的索引位置检索独享,Li ...
- HADOOP cluster some issue for installation
给namenode搭建了HA,然后根据网上的配置也配置了secondary namenode, 但是一直没有从日志中看到启动secondnary namenode,当然进程也没有. 找了很多资料,按照 ...
- [转]Javascript中的自执行函数表达式
[转]Javascript中的自执行函数表达式 本文转载自:http://www.ghugo.com/javascript-auto-run-function/ 以下是正文: Posted on 20 ...
- hdu 5800 To My Girlfriend + dp
传送门:hdu 5800 To My Girlfriend 题意:给定n个物品,其中i,j必选,l,m必不选,问组成体积为s的方法一共有多少种 思路:定义dp[i][j][s1][s2],表示前i种物 ...
- POJ 1066 Treasure Hunt --几何,线段相交
题意: 正方形的房子,给一些墙,墙在区域内是封闭的,给你人的坐标,每穿过一道墙需要一把钥匙,问走出正方形需要多少把钥匙. 解法: 因为墙是封闭的,所以绕路也不会减少通过的墙的个数,还不如不绕路走直线, ...
- HDU 4041 Eliminate Witches! --模拟
题意: 给一个字符串,表示一颗树,要求你把它整理出来,节点从1开始编号,还要输出树边. 解法: 模拟即可.因为由括号,所以可以递归地求,用map存对应关系,np存ind->name的映射,每进入 ...