C++设计模式七--CommandPattern(命令模式)
来源:互联网 发布:手机zip解压软件 编辑:程序博客网 时间:2024/06/01 09:55
定义
命令模式将“请求”封装成对象,以便使用不同的请求、队列或者日志来参数化其他对象。命令模式也支持可撤销的操作。
要点
1)命令模式将调用者和接受者对象解耦。
2)被解耦的两者之间是通过命令对象进行沟通的。命令对象封装了接受者和一个或者一组动作。
3)调用者通过调用命令对象的execute()发出请求,这会使得接收者的动作被调用。
4)调用者可以接受命令对象当做参数,甚至在运行时动态地进行。
5)命令可以支持撤销,做法是实现一个undo()方法来回到execute()倍执行前的状态。
6)命令可以用来实现日志和事务系统。
类图
Invoker:调用者持有一个命令对象,并在某个时间点调用命令对象的execute()方法,将请求付诸行动。
Command:为所有命令声明一个接口。调用命令对象的execute()方法,就可以就可以让接收者进行相关的动作。这个接口也具备一个undo()方法。
Receiver:接收者知道如何进行必要的工作,实现这个请求。任何类都可以做接收者。
示例
下面模拟一个遥控器程序,来控制电灯和音响的开关。
Light.h
#ifndef LIGHT_H#define LIGHT_H#include <string>#include <iostream>using std::string;using std::cout;using std::endl;// 灯(Receiver)class Light{public: Light(string n): name(n) {} ~Light(){} void on() { cout << name << " is on" << endl; } void off() { cout << name << " is off" << endl; }private: string name;};#endif
Stereo.h
#ifndef STEREO_H#define STEREO_H#include <string>#include <iostream>using std::string;using std::cout;using std::endl;// 音响(Receiver)class Stereo{public: Stereo(string n): name(n) {} ~Stereo(){} void on() { cout << name << " is on" << endl; } void off() { cout << name << " is off" << endl; }private: string name;};#endif
Command.h
#ifndef COMMAND_H#define COMMAND_H#include "Light.h"#include "Stereo.h"// 命令接口class Command{public: Command(){} virtual~Command(){} virtual void execute() = 0; virtual void undo() = 0;};// 空命令class NoCommand : public Command {public: NoCommand(){} ~NoCommand(){} void execute(){} void undo(){}};// 开灯命令class LightOnCommand: public Command{public: LightOnCommand(Light *l): light(l) { } ~LightOnCommand(){} void execute() { light->on(); } void undo() { light->off(); }private: Light *light;};// 关灯命令class LightOffCommand: public Command{public: LightOffCommand(Light *l): light(l) { } ~LightOffCommand(){} void execute() { light->off(); } void undo() { light->on(); }private: Light *light;};// 开音响命令class StereoOnCommand: public Command{public: StereoOnCommand(Stereo *s): stereo(s) { } ~StereoOnCommand(){} void execute() { stereo->on(); } void undo() { stereo->off(); }private: Stereo *stereo;};// 关音响命令class StereoOffCommand: public Command{public: StereoOffCommand(Stereo *s): stereo(s) { } ~StereoOffCommand(){} void execute() { stereo->off(); } void undo() { stereo->on(); }private: Stereo *stereo;};// 遥控器(Invoker)class RemoteControl {private: Command* onCommands[7]; // 最多控制7个设备 Command* offCommands[7]; Command* undoCommand; Command* noCommand;public: RemoteControl() { noCommand = new NoCommand(); for (int i=0; i<7; i++) { onCommands[i] = noCommand; offCommands[i] = noCommand; } undoCommand = noCommand; } ~RemoteControl() { delete noCommand; } void setCommand(int slot, Command* onCommand, Command* offCommand) { onCommands[slot] = onCommand; offCommands[slot] = offCommand; } void onButtonWasPushed(int slot) { onCommands[slot]->execute(); undoCommand = onCommands[slot]; } void offButtonWasPushed(int slot) { offCommands[slot]->execute(); undoCommand = offCommands[slot]; } void undoButtonWasPushed() { undoCommand->undo(); }};// 批量命令(Invoker)class MacroCommand: public Command{private: Command** command; int cnt;public: MacroCommand(Command** cmd, int c): command(cmd), cnt(c) { } ~MacroCommand(){} void execute() { for (int i=0; i<cnt; i++) { command[i]->execute(); } } void undo() { for (int i=0; i<cnt; i++) { command[i]->undo(); } }};#endif
main.cpp
#include "Command.h"int main(){ Light *light = new Light("Simple light"); Stereo *stereo = new Stereo("Cool stereo"); LightOnCommand *loc = new LightOnCommand(light); LightOffCommand *lofc = new LightOffCommand(light); StereoOnCommand *soc = new StereoOnCommand(stereo); StereoOffCommand *sofc = new StereoOffCommand(stereo); RemoteControl* remoteControl = new RemoteControl(); remoteControl->setCommand(0, loc, lofc); remoteControl->setCommand(1, soc, sofc); remoteControl->onButtonWasPushed(0); remoteControl->offButtonWasPushed(0); remoteControl->onButtonWasPushed(1); remoteControl->offButtonWasPushed(1); remoteControl->undoButtonWasPushed(); cout << "==============================" << endl; Command* cmd[2] = {loc, soc}; MacroCommand* macroCommand = new MacroCommand(cmd, 2); macroCommand->execute(); macroCommand->undo(); delete macroCommand; delete remoteControl; delete sofc; delete soc; delete lofc; delete loc; delete stereo; delete light; return 0;}
Makefile
CXX = g++CFLAGS = -WallLDFLAGS = target = ressrcs = main.cppobjs = $(srcs:.cpp=.o)headers = $(wildcard *.h).PHONY: allall: $(target)$(target): $(objs) $(headers) $(CXX) $(LDFLAGS) -o $(target) $(objs)$(objs):%.o:%.cpp $(CXX) $(CFLAGS) -c -o $@ $<clean: rm -f $(target) *.o
测试
测试结果如下图所示:
阅读全文
1 0
- C++设计模式七--CommandPattern(命令模式)
- 命令模式(CommandPattern)
- Head First 设计模式之命令模式(CommandPattern)
- 命令模式 CommandPattern
- 命令模式CommandPattern
- 设计模式之七 命令模式(Command Pattern)
- 设计模式之七:命令模式(Command Pattern)
- 设计模式系列(七)——命令模式
- Python设计模式(七)【命令模式】
- 设计模式(c++)笔记之七(Adapter模式)
- 设计模式(七)
- C语言和设计模式(命令模式)
- C语言和设计模式(命令模式)
- C语言和设计模式(命令模式)
- 04.C语言和设计模式(命令模式)
- 13、C语言和设计模式(命令模式)
- 设计模式——命令模式(C++)
- C语言设计模式:命令模式 //tbd
- H.264 视频编码器的研究与分析
- 有关GCC的基本用法
- 华为笔试最高分代码问题
- C#中如何通过HTTP协议的不同请求方式获取数据
- 主动申请权限
- C++设计模式七--CommandPattern(命令模式)
- 用java和二叉树B-tree实现具有<增,删,改,查,统计>功能的简易数据库(不使用数组或集合)
- codeforces 133A(HQ9+) Java
- lstm在文本分类中的作用
- 设计原则-里氏替换原则
- 【编程】AWK文本处理命令学习-文本处理利器
- eclipse调试快捷键
- C/C++:调用函数来初始化全局变量
- 准备新的开始