概述

命令模式的结构很简单,但是对于消除代码间的耦合却有着重要的影响。命令模式就是一个函数对象:一个作为对象的函数。通过将函数封装为对象,就能够以参数的形式将其传递给其他函数或者对象,告诉它们在旅行请求的过程中执行特定的操作。

命令模式

根据以上定义,来看一个简单的示例:

/*** 命令模式,消除代码间的耦合*/
#include <iostream>
#include <vector>using namespace std;class Command
{
public:virtual void excute() = 0;virtual ~Command();
};class Hello : public Command
{
public:void excute(){cout << "Hello ";}virtual ~Hello();
};
class World : public Command
{
public:void excute(){cout << "World! ";}virtual ~World();
};
class IAm : public Command
{
public:void excute(){cout << "I'm the command pattern ";}virtual ~IAm();
};class Macro
{
public:void add(Command* c){commands.push_back(c);}void run(){vector<Command*>::iterator it = commands.begin();while(it != commands.end()){(*it++)->excute();}}
private:vector<Command*> commands;
};int main()
{Macro macro;macro.add(new Hello);macro.add(new World);macro.add(new IAm);macro.run();return 0;
}

命令模式的最主要特点是允许一个函数或者对象传递一个想要的动作,上述示例提供了将一系列想要一起执行的动作集进行排队的方法。

命令模式一个常见的例子就是在应用程序中“撤销操作”功能的实现,没在在用户进行某项操作的时候,相应的“撤销操作”命令对象就被置入一个队列中,而每个命令对象被执行之后,程序的状态就倒退一步。

利用命令模式消除与事件处理的耦合

命令模式可用来消除程序中的耦合问题。每个“常规”的操作必须周期性地调用一个函数来检查事件的状态,而通过命令模式,这些“常规”操作不需要知道有关它们所检查的事件的任何信息,也就是说它们已经与事件处理代码分离开来。

示例:

#include <iostream>
#include <vector>
#include <string>
#include <ctime>
#include <cstdlib>using namespace std;class Task
{
public:virtual void operation() = 0;
};//单例
class TaskRunner
{
public:static void add(Task& t){tasks.push_back(&t);}static void run(){vector<Task*>::iterator it = tasks.begin();while (it != tasks.end()) {(*it++)->operation();}}private:static vector<Task*> tasks;TaskRunner(){}static TaskRunner tr;
};TaskRunner TaskRunner::tr;
vector<Task*> TaskRunner::tasks;//创建随机延迟时间
//clock() 返回从开启程序进程到调用clock()时的时间。
class EventSimulator
{
public:EventSimulator():creation(clock()) {delay = CLOCKS_PER_SEC/4 * (rand() % 20 + 1);cout << "delay = " << delay << endl;}bool fired(){return clock() > creation + delay;}private:clock_t creation;clock_t delay;
};class Button{
public:Button(string name):pressed(false),id(name){}void press(){pressed = true;}bool isPressed(){if(e.fired()) press();return pressed;}friend ostream& operator <<(ostream & os,const Button& b){return os << b.id;}private:bool pressed;string id;EventSimulator e;
};class CheckButton : public Task
{
public:CheckButton(Button & b):button(b),handled(false) {}void operation(){if(button.isPressed() && !handled){cout << button << " pressed" << endl;handled = true;}}private:Button & button;bool handled;
};void procedure1(){TaskRunner::run(); // check all events
}
void procedure2(){TaskRunner::run(); // check all events
}
void procedure3(){TaskRunner::run(); // check all events
}int main()
{srand(time(0));Button b1("Button 1"),b2("Button 2"),b3("Button 3");CheckButton cb1(b1),cb2(b2),cb3(b3);TaskRunner::add(cb1);TaskRunner::add(cb2);TaskRunner::add(cb3);cout<< "Control-C to exit" << endl;while (true) {procedure1();procedure2();procedure3();}return 0;
}

输出为:

delay = 4500000
delay = 3000000
delay = 3000000
Control-C to exit
Button 2 pressed
Button 3 pressed
Button 1 pressed

这个示例中,命令对象由被单例 TaskRunner执行的 Task 表示。EventSimulator创建一个随机延迟时间,所以当周期性的调用函数fired()时,在某个随机时间段,其返回结果从 true 和 false 变化。EventSimulator对象类 Button 中使用,模拟在某个不可预知的时间段用户时间发生的动作。CheckButton 是Task 的实现,在程序中通过所有“正常”代码对其进行周期性检查,就是这里的procedure1(),procedure2(),procedure3()的末尾。

参考资料《C++编程思想》。

C++设计模式--命令模式(Command)相关推荐

  1. 设计模式:命令模式(Command Pattern)

    命令模式(Command Pattern): 在软件设计中,我们经常需要向某些对象发送请求,但是并不知道请求的接受者是谁,也不知道请求的操作是哪个. 我们只需在程序运行时指定具体的请求接受者即可,此时 ...

  2. 设计模式 - 命令模式(command pattern) 撤销(undo) 具体解释

    命令模式(command pattern) 撤销(undo) 详细解释 本文地址: http://blog.csdn.net/caroline_wendy 參考命令模式: http://blog.cs ...

  3. 解读设计模式----命令模式(Command Pattern)

    ***本文与作者原文有一定的偏差,其中加入了一部分是个人看法,详细请查看作者原文.*** 原文连接http://www.dofactory.com/Patterns/PatternCommand.as ...

  4. Java设计模式-命令模式Command

    定义 将来自客户端的请求传入一个对象,从而使你可用不同的请求对客户进行参数化.用于"行为请求者"与"行为实现者"解耦,可实现二者之间的松耦合,以便适应变化.分离 ...

  5. 趣谈设计模式 | 命令模式(Command):将命令封装为对象

    文章目录 案例:智能遥控 命令模式 应用场景 队列请求 日志系统 总结 完整代码与文档 命令模式的应用场景较少,且不易理解,因此我也不好举例,所以下面的描述可能会存在一些问题,请见谅 案例:智能遥控 ...

  6. 设计模式-命令模式(Command)

    关注公众号 JavaStorm 获取更多成长. 大约需要6分钟读完.建议收藏后阅读. 命令模式把一个请求或者操作封装到一个对象中.命令模式允许系统使用不同的请求把客户端参数化,对请求排队或者记录请求日 ...

  7. 【白话设计模式八】命令模式(Command)

    为什么80%的码农都做不了架构师?>>>    #0 系列目录# 白话设计模式 工厂模式 单例模式 [白话设计模式一]简单工厂模式(Simple Factory) [白话设计模式二] ...

  8. 乐在其中设计模式(C#) - 命令模式(Command Pattern)

    原文:乐在其中设计模式(C#) - 命令模式(Command Pattern) [索引页] [源码下载] 乐在其中设计模式(C#) - 命令模式(Command Pattern) 作者:webabcd ...

  9. C++设计模式——命令模式(command pattern)

    一.原理讲解 别名动作(action),事务(transaction). 1.1意图 将一个请求封装为一个对象,从而使我们可用不同的请求对客户进行参数化,对请求排队或记录请求日志,以及支持可撤销的操作 ...

最新文章

  1. Swoft 2 Beta 发布,基于 Swoole 的云原生协程框架
  2. ElasticSearch 2 (26) - 语言处理系列之打字或拼写错误
  3. 将 Mac OS X 上的目录挂载到 Linux 的方法
  4. 禅道 bug状态 open_小工具大帮手,利用 @open-node/antman 实现 node.js 进程线上调试,无须重启...
  5. 太监式的自主知识产权研发特色 (Z)
  6. 阿里云 超级码力在线编程大赛初赛 第3场 题目1. 最大公倍数
  7. 理论基础 —— 二叉树 —— 二叉树的遍历
  8. C# 打开指定文件夹下的excel
  9. 小D课堂 - 零基础入门SpringBoot2.X到实战_第14节 高级篇幅之SpringBoot多环境配置_59、SpringBoot多环境配置介绍和项目实战...
  10. 7-4 统计素数并求和
  11. 若依ruoyi框架整合magic-api快速开发
  12. 计算机办公模式是什么,华为Mate 10“电脑模式”告诉你什么是真正的“移动办公”...
  13. React组件通信-父子组件间的通信
  14. android怎么实现广告页,Android开屏广告的实现原理与适配方案
  15. 继续:个人微信的自动收款解决(思路)
  16. 西工大计算机考研最全的报名和各方向解析,含导师介绍
  17. 14. RDMA之Memory Window
  18. 【机器学习】缺失值的处理方法总结
  19. 输出1-100之内的所有质数
  20. qq登录 适用于 laravel

热门文章

  1. 推荐系统User-Item Embedding图算法
  2. Learning to Rank:X-wise
  3. 云信迎来五周年里程碑:日活破3亿,消息量破10000亿
  4. 推进教育人工智能?网易云和网易波特 “四步走”
  5. Flex Basis与Width的区别
  6. 只知道ajax?你已经out了
  7. U盘容量减少的解决办法
  8. 单片机驱动DM9000网卡芯片(详细调试过程)【下】
  9. C++回调函数用法(zt)
  10. vsFTP服务器的配置