C++之命令(Command)模式
0. 简介
我们在遇到类似GUI中多种Button点击功能的操作时,我们应该将请求的所有细节 (例如调用的对象、 方法名称和参数列表) 抽取出来组成命令类, 该类中仅包含一个用于触发请求的方法。
命令模式就是这样一种行为设计模式, 它可将请求转换为一个包含与请求相关的所有信息的独立对象。 并能根据不同的请求将方法参数化、 延迟请求执行或将其放入队列中, 且能实现可撤销操作。
1. 命令模式示意图
命令模式可将特定的方法调用转化为独立对象。 这一改变也带来了许多有趣的应用: 你可以将命令作为方法的参数进行传递、 将命令保存在其他对象中, 或者在运行时切换已连接的命令等。
Command(抽象命令类):抽象出命令对象,可以根据不同的命令类型。写出不同的实现类
Concrete Command(具体命令类):实现了抽象命令对象的具体实现
Invoker(调用者/请求者):请求的发送者,它通过命令对象来执行请求。一个调用者并不需要在设计时确定其接收者,因此它只与抽象命令来之间存在关联。在程序运行时,将调用命令对象的execute() ,间接调用接收者的相关操作。
Receiver(接收者):接收者执行与请求相关的操作,真正执行命令的对象。具体实现对请求的业务处理。未抽象前,实际执行操作内容的对象。
Client(客户端):在客户类中需要创建调用者对象,具体命令类对象,在创建具体命令对象时指定对应的接收者。发送者和接收者之间没有之间关系。都通过命令对象来调用。
2. 示例程序
责任链模式和命令模式用于处理请求发送者和接收者之间的不同连接方式。责任链按照顺序将请求动态传递给一系列的潜在接收者, 直至其中一名接收者对请求进行处理。命令模式则是在发送者和请求者之间建立单向连接。
作为命令模式的作用,非常明显,它可以通过某些行为来参数化对象。从而避免了继承导致的调用与接收的紧耦合。命令模式则是分离了这两者,修改时只需要添加接收者并创建新的实例化具体命令类即可实现整套代码的调用。
#include <iostream>
#include <string>
#include <vector>
#include <algorithm>
#include <iterator>using namespace std;// 接受者,作为最底层的调用
class Receiver
{public:void BakeMutton(){cout<< "烤羊肉"<< endl;}void BakeChicken(){cout<< "烤鸡翅"<< endl;}
};// 基类
class Command
{public:Command(Receiver* pstReceiver):m_pstReceiver(pstReceiver){}virtual void Excute() = 0;protected:Receiver* m_pstReceiver;
};// 具体类,用于调用接收者
class ConcreteCommandA: public Command
{public:ConcreteCommandA(Receiver* pstReceiver):Command(pstReceiver){}virtual void Excute(){cout<< "ConcreteCommandA excuting......"<< endl;m_pstReceiver->BakeMutton();}};// 具体类,用于调用接收者
class ConcreteCommandB: public Command
{public:ConcreteCommandB(Receiver* pstReceiver):Command(pstReceiver){}virtual void Excute(){cout<< "ConcreteCommandB excuting......"<< endl;m_pstReceiver->BakeChicken();}
};// 调用者,作为最上层,用于管理具体类的操作,从而对接收者增删
class Invoke
{public:void Add(Command* pstCommand){m_vecPstCommand.push_back(pstCommand);}void Remove(Command* pstCommand){m_vecPstCommand.erase(find(m_vecPstCommand.begin(), m_vecPstCommand.end(), pstCommand));}void RemoveAll(){m_vecPstCommand.clear();}void Notify(){for (typeof(m_vecPstCommand.begin()) it = m_vecPstCommand.begin(); it != m_vecPstCommand.end(); ++it){(*it)->Excute();}}private:vector<Command*> m_vecPstCommand;
};int main(int argc, char* argv[])
{Receiver* pstReceiver = new Receiver();Command* pstConcreteCommandA = new ConcreteCommandA(pstReceiver);Command* pstConcreteCommandB = new ConcreteCommandB(pstReceiver);Invoke* pstInvoke = new Invoke();pstInvoke->Add(pstConcreteCommandA);pstInvoke->Add(pstConcreteCommandA);pstInvoke->Add(pstConcreteCommandB);pstInvoke->Notify();cout<< "------------------"<< endl<< endl;pstInvoke->Remove(pstConcreteCommandA); //撤销操作pstInvoke->Remove(pstConcreteCommandB);pstInvoke->Notify();cout<< "------------------"<< endl<< endl;return 0;
}/**
ConcreteCommandA excuting......
烤羊肉
ConcreteCommandA excuting......
烤羊肉
ConcreteCommandB excuting......
烤鸡翅
------------------ConcreteCommandA excuting......
烤羊肉
------------------
**/
…详情请参照古月居
C++之命令(Command)模式相关推荐
- 设计模式学习笔记——命令(Command)模式
设计模式学习笔记--命令(Command)模式 @(设计模式)[设计模式, 命令模式, command] 设计模式学习笔记命令Command模式 基本介绍 命令案例 类图 实现代码 Command接口 ...
- 设计模式--命令(Command)模式
模式定义 将一个请求(行为)封装为一个对象,从而使你可用不同的请求对客户进行参数化,对请求排队或记录请求日志,以及支持可撤销的操作 类图 要点总结 Command模式的根本目的在于将"行为请 ...
- python中command是什么意思_python 设计模式之命令(Command)模式
#写在前面 也了解了不少设计模式了,他们都有一个通病,那就是喜欢把简单的东西复杂化.比如在不同的类中加个第三者.哈哈哈,简单变复杂是有目的的,那就是降低耦合度,增强可维护性,提高代码复用性,使代码变得 ...
- .NET中的Command(命令)模式
在Command(命令)模式中,使用对象来表示和封装稍后调用该方法所需的全部信息--这些信息包括方法名.拥有该方法的对象.及参数值.在系列文章".NET中的Command(命令)模式&quo ...
- php yii 命令行,命令行模式(Command)
命令行模式(Command) 3.2.1. 目的 为了封装调用和解耦. 我们有一个调用程序和一个接收器. 这种模式使用「命令行」将方法调用委托给接收器并且呈现相同的「执行」方法. 因此,调用程序只知道 ...
- 命令模式(Command模式)详解
在软件开发系统中,常常出现"方法的请求者"与"方法的实现者"之间存在紧密的耦合关系.这不利于软件功能的扩展与维护.例如,想对行为进行"撤销.重做.记录 ...
- Command(命令)模式
目录 前言 一.命令模式总结 1.模式意图 2.参与者 3.结构.协作.适用性及效果 二.命令模式简单示例 1.用例描述 2.示例代码 总结 前言 本周五参加了Command(命令 )模式研讨会,本文 ...
- Command模式的实践
Command模式的实践 主题 文章将通过一个简单的 Shell 库来阐述 Command模式的一个实际应用. 如何使用 Shell 库 在开始之前,我们先来看看如何使用这个 Shell 库. 解决 ...
- 使用Command模式实现撤销机制 (Code Project 精选翻译)
使用Command模式实现撤销机制[1] Written by Matt Berther Translated by Allen Lee[2] Reviewed by Teddy Tam & ...
最新文章
- 功率半导体碳化硅(SiC)技术
- 开发者,只有被裁,没有退休
- python哪本好-最好的Python入门教材是哪本?
- 利用OpenCV的threshold函数实现双阈值法二值化操作的源码
- texlive2015+texstudio
- autoencoder自编码器原理以及在mnist数据集上的实现
- 项目部署服务器 jstl,Springboot集成jsp及部署服务器实现原理
- springMVC之与json数据交互方法
- 分布式系统关注点(20)——阻塞与非阻塞有什么区别?
- 判断存储,是栈?还是队列?
- Linux内核源代码分析-第二章 代码初识-2
- 网件r7000梅林系统5g不稳定 5g信号经常掉线解决方法
- Django之路由配置(url与path及re_path区别)
- draw.io怎么安装在linux,Draw.io安装
- 网络OSI七层及各层作用
- 系统集成资质培训 - 挣值分析题目分析
- Excel插入图片实现单击放大或缩小
- 【visual studio】错误LNK 1168,无法打开 XXX.exe进行写入解决方案
- Java8 stream sorted排序时包括null
- 写一些给程序员世界的话(不是什么所谓的正能量,但是的确是发自内心的实话)