设计模式之命令模式(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 ...
随机推荐
- IIC通讯协议(非原创,转载他人,用于学习)
I2C协议:1.空闲状态 2.开始信号 3.停止信号 4.应答信号 5.数据的有效性 6.数据传输 IIC详解 1.I2C总线具有两根双向信号线,一根是数据线SDA,另一根是时钟线SCL 2.IIC总 ...
- 浅析软件工程中的UML建模技术
一.基本信息 标题:浅析软件工程中的UML建模技术 时间:2018 出版源:电子世界 领域分类:软件工程:UML建模技术:需求分析 二.研究背景 问题定义:软件工程中UML建模技术的研究 难点:明确软 ...
- 20155326刘美岑 Exp6 信息收集与漏洞扫描
20155326刘美岑 Exp6 信息收集与漏洞扫描 实验后回答的问题 (1)哪些组织负责DNS,IP的管理. 全球根服务器均由美国政府授权的ICANN统一管理,负责全球的域名根服务器.DNS和IP地 ...
- 2017-2018-1 20155326信息安全系统设计基础》嵌入式C语言课上考试补交
2017-2018-1 20155326信息安全系统设计基础>嵌入式C语言课上考试补交 PPT上的例子 已知位运算规则为: &0 --> 清零 &1 --> 不变 | ...
- 网页中的数据的4个处理方式:CRUD(Creat, Retrive, Update, Delete)
网页中的数据的4个处理方式:CRUD(Creat, Retrive, Update, Delete) 2018-12-21, 后续完善
- EF db first 获取表名称
一直以来,使用DB FIRST的方式,想得到表名,最后一直不得其法.直到昨天晚上,反编译自己的程序集的时候,突然发现EF表结构和数据实体类的映射关系存在什么地方.然后就有了这篇文章. 咱们一步步来. ...
- 机器学习随笔01 - k近邻算法
算法名称: k近邻算法 (kNN: k-Nearest Neighbor) 问题提出: 根据已有对象的归类数据,给新对象(事物)归类. 核心思想: 将对象分解为特征,因为对象的特征决定了事对象的分类. ...
- IDEA中读取 resource目录下文件
1. 资源文件 2. 加载文件 public void test() { try { System.out.println("begin test"); String filepa ...
- 第三篇: 服务消费者(Feign)
本文根据https://blog.csdn.net/forezp/article/details/81040965写出,修正了部分瑕疵,在此对那位博主表示感谢. 上一篇文章讲述通过RestTempla ...
- 使用Ansible实现数据中心自动化运维管理
长久以来,IT 运维在企业内部一直是个耗人耗力的事情.随着虚拟化的大量应用.私有云.容器的不断普及,数据中心内部的压力愈发增加.传统的自动化工具,往往是面向于数据中心特定的一类对象,例如操作系统.虚拟 ...