命令模式
将一个请求封装为一个对象,从而让我们可用不同的请求对客户进行参数化;对请求排队或者记录请求日志,以及支持可撤销的操作。命令模式是一种对象行为型模式,其别名为动作(Action)模式或事务(Transaction)模式。
命令模式可以将请求发送者和接收者完全解耦,发送者与接收者之间没有直接引用关系,发送请求的对象只需要知道如何发送请求,而不必知道如何完成请求
基本类型图:
例子类型:
代码:
#define _CRT_SECURE_NO_WARNINGS
#include "stdafx.h"
#include <iostream>
#include <list>
using namespace std;
//系统的一个核心类模块
class Doctor
{
public:
//治疗眼睛的方法
void treatEyes() {
cout << "医生治疗了眼睛" << endl;
}
//治疗鼻子的方法
void treatNose() {
cout << "医生治疗的鼻子" << endl;
}
};
//定义一个抽象的病单
class Command
{
public:
Command(Doctor *doctor)
{
this->doctor = doctor;
}
~Command() {
if (this->doctor != NULL) {
delete doctor;
doctor = NULL;
}
}
virtual void treat() = 0;
protected:
Doctor *doctor;
};
//治疗眼睛的病单
class CommandEyes :public Command
{
public:
CommandEyes(Doctor *doctor) :Command(doctor) {}
//病单执行治疗的时候,实际上让医生治疗
void treat() {
doctor->treatEyes();//命令让最终的执行者 干活。
}
};
//治疗鼻子的病单
class CommandNose :public Command
{
public:
CommandNose(Doctor *doctor) :Command(doctor)
{
}
virtual void treat() {
doctor->treatNose();
}
};
//护士类
class Nurse
{
public:
Nurse(Command *cmd)
{
this->cmd = cmd;
}
~Nurse() {
if (this->cmd != NULL) {
delete this->cmd;
}
}
//下发病单的方法
void notify() {
this->cmd->treat();
}
private:
Command *cmd;
};
//护士长
class NurseBoss
{
public:
NurseBoss()
{
m_list.clear();
}
~NurseBoss() {
m_list.clear();
}
//给护士长添加病单的方法
void setCmd(Command *cmd)
{
this->m_list.push_back(cmd);
}
//下发手里所有病单的指令
void notify()
{
for (list<Command*>::iterator it = m_list.begin(); it != m_list.end(); it++)
{
(*it)->treat(); // 会发生多态, Command 是所有命令的父类。
}
}
private:
list<Command*> m_list;
};
int main(void)
{
NurseBoss *woman = new NurseBoss;
Command *cmd1 = new CommandEyes(new Doctor);
Command *cmd2 = new CommandNose(new Doctor);
//将所有指令都给护士长
woman->setCmd(cmd1);
woman->setCmd(cmd2);
woman->notify();
return 0;
}
代码输出:
医生治疗了眼睛
医生治疗的鼻子
命令模式的优缺点
优点:
(1) 降低系统的耦合度。 由于请求者与接收者之间不存在直接引用,因此请
求者与接收者之间实现完全解耦,相同的请求者可以对应不同的接收者,同样,
相同的接收者也可以供不同的请求者使用,两者之间具有良好的独立性。
(2) 新的命令可以很容易地加入到系统中。 由于增加新的具体命令类不会影
响到其他类,因此增加新的具体命令类很容易,无须修改原有系统源代码,甚
至客户类代码,满足“开闭原则”的要求。
(3) 可以比较容易地设计一个命令队列或宏命令(组合命令)。
缺点:
使用命令模式可能会导致某些系统有过多的具体命令类。 因为针对每一个
对请求接收者的调用操作都需要设计一个具体命令类,因此在某些系统中可能
需要提供大量的具体命令类,这将影响命令模式的使用。
喜欢我的博客的同学可以关注与支持,让我们一起进步学习。坚持就是胜利,无论如何都要坚持下去,首先要战胜自己。