设计模式之命令模式(Command )
命令模式是我们能够实现发送者和接收者之间的完全解耦,发送者是调用操作的对象,而接收者是接收请求并执行特定操作的对象。通过解耦,发送者无需了解接收者的接口。在这里,请求的含义是需要被执行的命令。
作用
将一个请求封装为一个对象,从而使你可用不同的请求对客户进行参数化;对请求排队或记录请求日志,以及支持可撤销的操作。当将客户的单个请求封装成对象以后,我们就可以对这个请求存储更多的信息,使请求拥有更多的能力;命令模式能够把请求发送者和接收者解耦,使得命令发送者不用去关心请求将以何种方式被处理。
类视图
实现
class Command;
/*调用者(Invoker)*/
class Switch
{
public:
Switch(){}
~Switch(){}
void insertcommand(Command* pCom)
{
m_command.pus_back(pCom);
}
void excuteonce()
{
if (m_command.empty())
return;
m_command.front()->excute();
m_command.pop_front();
}
private:
list< share_prt<Command*> > m_command;
};
/*接收者(Recever)*/
class Appliance
{
public:
Appliance(){}
virtual ~Appliance(){}
virtual bool start() = 0;
virtual bool stop() = 0;
};
class AirConditioner : public Appliance
{
public:
AirConditioner(){}
virtual ~AirConditioner(){}
bool start()
{
cout <<"the air conditioner is on" << endl;
}
bool stop()
{
cout <<"the air conditioner is off" << endl;
}
};
class Fridge : public Appliance
public:
Fridge(){}
virtual ~Fridge(){}
bool On()
{
cout <<"the firdge is on" << endl;
}
bool Off()
{
cout <<"the firdge is off" << endl;
}
};
/*命令(Command)*/
class Command
{
public:
Command(Appliance* pAl): m_pAlice(pAl){}
virtual ~Command(){}
virtual excute();
protected:
Appliance* m_pAlice;
};
class OnCommand : public Command
{
public:
OnCommand(Appliance* pAl): Command(pAl){}
virtual ~OnCommand(){}
bool excute()
{
m_pAlice.On();
}
};
class OffCommand : public Command
{
public:
OffCommand(Appliance* pAl): Command(pAl){}
virtual ~OffCommand(){}
bool excute()
{
m_pAlice.Off();
}
};
int main()
{
//接收者
AirConditioner air;
Fridge fridge;
//生成命令
OnCommand On1(&air);
OnCommand On2(&fridge);
OffCommand off1(&air);
OffCommand off2(&fridge);
//发送命令
Switch switcher;
switcher.insertcommand(&on1);
switcher.insertcommand(&on2);
switcher.insertcommand(&off1);
switcher.insertcommand(&off2);
//执行命令
switcher.excuteonce();
switcher.excuteonce();
switcher.excuteonce();
switcher.excuteonce();
}
从如上的例子中可以分析出,调用者switch不会关心是开命令还是关命令,是属于空调的命令还是冰箱的命令,这样一方面可以做到解耦的效果,另一方面,还可以对接收者和命令进行方便的扩展,这就是命令模式的核心优点所在。当然缺点也正是如此,接收者和命令的组合数量是MxN的关系,再扩展是需要注意数量级的大小。
应用场景
- 通过参数化对象实现功能执行,命令是面向对象式的,而不是回调函数式的;
- 指定消息队列并在不同时间执行请求。一个命令对象可以有独立于原始请求的生命周期。如果一个请求的接收者可以由一个独立地址空间的方式来表示,那么你可以将请求对象的命令转换到不同的进程空间并在其中完成请求。
- 支持撤销。命令的执行操作可以作为状态进行存储,并在需要时实现命令撤销,命令的接口必须增加一个unexcude操作,进行撤销操作的执行。
- 支持日志记录变化,在系统崩溃的情况下使用命令可以重新应用。通过增加load和store操作命令接口,可以保存一个持续变化的日志,从系统崩溃中恢复,需要重新加载日志命令和使用excute操作重新执行这些命令。
- 通过在原生操作基础上的高层操作构建系统。这样的结构在支持交易操作的系统中很常见。一个交易事物封装一组变化的数据,命令模式提供了一种交易模型,命令都有一个共同的接口,允许你使用相同的方式调用所有的交易。这种模式也使得它很容易与新的交易系统进行交互扩展。
设计模式之命令模式(Command )的更多相关文章
- 设计模式 ( 十三 ) 命令模式Command(对象行为型)
设计模式 ( 十三 ) 命令模式Command(对象行为型) 1.概述 在软件设计中,我们经常需要向某些对象发送请求,但是并不知道请求的接收者是谁,也不知道被请求的操作是哪个,我们只需 ...
- 乐在其中设计模式(C#) - 命令模式(Command Pattern)
原文:乐在其中设计模式(C#) - 命令模式(Command Pattern) [索引页][源码下载] 乐在其中设计模式(C#) - 命令模式(Command Pattern) 作者:webabcd ...
- 面向对象设计模式_命令模式(Command)解读
在.Net框架中很多对象的方法中都会有Invoke方法,这种方法的设计实际是用了设计模式的命令模式, 模式图如下 其核心思路是将Client 向Receiver发送的命令行为进行抽象(ICommand ...
- 二十四种设计模式:命令模式(Command Pattern)
命令模式(Command Pattern) 介绍将一个请求封装为一个对象,从而使你可用不同的请求对客户进行参数化:对请求排队或记录请求日志,以及支持可取消的操作. 示例有一个Message实体类,某个 ...
- 设计模式-15命令模式(Command Pattern)
1.模式动机 在软件设计中,我们经常需要向某些对象发送请求,但是并不知道请求的接收者是谁,也不知道被请求的操作是哪个,我们只需在程序运行时指定具体的请求接收者即可,此时,可以使用命令模式来进行设计,使 ...
- [设计模式] 14 命令模式 Command
Command 模式通过将请求封装到一个对象(Command)中,并将请求的接受者存放到具体的 ConcreteCommand 类中(Receiver)中,从而实现调用操作的对象和操作的具体实现者之间 ...
- 设计模式之命令模式(Command)摘录
23种GOF设计模式一般分为三大类:创建型模式.结构型模式.行为模式. 创建型模式抽象了实例化过程,它们帮助一个系统独立于怎样创建.组合和表示它的那些对象.一个类创建型模式使用继承改变被实例化的类,而 ...
- 大熊君说说JS与设计模式之------命令模式Command
一,总体概要 1,笔者浅谈 日常生活中,我们在看电视的时候,通过遥控器选择我们喜欢的频道时,此时我们就是客户端的角色,遥控器的按钮相当于客户请求,而具体执行的对象就是命令对象, 命令模式把一个请求或者 ...
- 设计模式 笔记 命令模式 Command
//---------------------------15/04/25---------------------------- //Conmmand 命令模式----对象行为型模式 /* 1:意 ...
- 行为型设计模式之命令模式(Command)
结构 意图 将一个请求封装为一个对象,从而使你可用不同的请求对客户进行参数化:对请求排队或记录请求日志,以及支持可撤消的操作. 适用性 抽象出待执行的动作以参数化某对象,你可用过程语言中的回调(c a ...
随机推荐
- JDBC几种常见的数据库连接
JDBC的URL=协议名+子协议名+数据源名.a 协议名总是“jdbc”.b 子协议名由JDBC驱动程序的编写者决定.c 数据源名也可能包含用户与口令等信息:这些信息也可单独提供.几种常见的数据库连接 ...
- Monkey测试简介【转载】
转载:https://www.xuebuyuan.com/3182523.html 一.Monkey测试简介 Monkey测试是Android平台自动化测试的一种手段,通过Monkey程序模拟用户触摸 ...
- SDWebImage源码分析
1.概述 SDWebImage是iOS开发中,被广泛使用的一个第三方开源库,提供了图片从加载.解析.处理.缓存.清理等一些列功能,让我们能够专心于业务的处理.本篇会从SDWebImage的源码,来一步 ...
- wpf使用FFMEPG录制屏幕
Simple function of recording screen based on ffmpeg Using WPF环境 Visual Studio 2017,dotNet Framework ...
- FTPClient 中 FTPClient.changeWorkingDirectory(filePath) 代码一直返回 false
FTP文件下载需要的jar包: commons-net-2.0.jar 有时可能还需要:jakarta-oro.jar 参考:FTPClient参考文档 这里记录下我碰到的问题: 刚开始我的账号和密 ...
- [CocoaPods]客户端加载第三方库
请先阅读另一篇博文铺垫知识基础:[CocoaPods]终端方式集成第三方库 客户端的Github地址:CocoaPods-app 点击下载客户端: [CocoaPods客户端] 安装下载的文件.软件界 ...
- 使用diskpart命令格式化U盘
在安装各种linux系统时,经常要使用SD卡,这里就出了个问题,就是SD卡被linux格式化之后无法在widdows下使用. 并且windows下的格式化按键对它毫无作用.笔者在摸索的过程中,找到了格 ...
- Shell - Shell脚本调试方法
Shell脚本调试选项 Shell本身提供一些调试方法选项: -n,读一遍脚本中的命令但不执行,用于检查脚本中的语法错误. -v,一边执行脚本,一边将执行过的脚本命令打印到标准输出. -x,提供跟踪执 ...
- Spring Cloud Finchley 正式发布,包含 4 个重大更新!
在 Spring 的官方博客上已经看到 Spring Cloud Finchley 在 06 月 19 日这一天正式发布了,我们在 Maven 中央仓库也看到了最新版的更新. Finchley 正式版 ...
- Liferay7 BPM门户开发之7: Activiti中的重要概念和主要数据库结构
流程的人员参与角色: Assignee :签收者(即待办人) Candidate:候选人 Owner:拥有者 Starter:启动者 participant:参与者,包含查阅 流程变量的类型: Str ...