定义
命令模式将“请求”封装成对象,以便使用不同的请求、队列或者日志来参数化其他对象。命令模式也支持可撤销的操作。
本文仅介绍将“请求”封装成对象,以便使用不同的请求。
定义命令模式类图
Client 负责创建具体命令。
Invoker 调用者,调用命令的execute 方法。
Command 为所有命令声明了一个接口。调用命令对象的exec 方法,就可以让接受者进行相关的动作。
具体命令继承自Command 接口。
命令模式的好处
- 调用者与接受者解耦
- 扩展命令非常方便
示例
- 定义接收者,Light.h
#pragma once
class Light
{
public:
Light();
~Light();
public:
void on();
void off();
};
- 定义接收者,Light.cpp
#include "Light.h"
#include <iostream>
using namespace std;
Light::Light()
{
}
Light::~Light()
{
}
void Light::on()
{
cout << "the light is on " << endl;
}
void Light::off()
{
cout << "the light is off " << endl;
}
- 定义开关灯的命令,BaseCommand.h
- #pragma once
class Light;
class BaseCommand
{
public:
BaseCommand();
virtual ~BaseCommand();
virtual void exec(Light* pLight) {};
virtual void release() { delete this; };
};
class LightOnCommand :public BaseCommand
{
public:
LightOnCommand();
virtual void exec(Light* pLight);
};
class LightOffCommand :public BaseCommand
{
public:
LightOffCommand();
virtual void exec(Light* pLight);
};
- 定义开关灯的命令,BaseCommand.cpp
#include "BaseCommand.h"
#include "Light.h"
BaseCommand::BaseCommand()
{
}
BaseCommand::~BaseCommand()
{
}
LightOnCommand::LightOnCommand()
{
}
void LightOnCommand::exec(Light * pLight)
{
if (pLight)
{
pLight->on();
}
}
LightOffCommand::LightOffCommand()
{
}
void LightOffCommand::exec(Light * pLight)
{
if (pLight)
{
pLight->off();
}
}
- 调用者,RemoteControl.h
#pragma once
class Light;
class BaseCommand;
class CRemoteControl
{
public:
CRemoteControl();
~CRemoteControl();
public:
void deliverCommand(BaseCommand* cmd);
protected:
Light * m_pLight;
};
- 调用者,RemoteControl.cpp
#include "Light.h"
#include "BaseCommand.h"
CRemoteControl::CRemoteControl()
{
m_pLight = new Light();
}
CRemoteControl::~CRemoteControl()
{
}
void CRemoteControl::deliverCommand(BaseCommand * cmd)
{
cmd->exec(m_pLight);
cmd->release();
}
- 主函数
int main()
{
CRemoteControl* pControl = new CRemoteControl();
LightOnCommand* pCommand = new LightOnCommand();
pControl->deliverCommand(pCommand);
LightOffCommand* pLightOffCmd = new LightOffCommand();
pControl->deliverCommand(pLightOffCmd);
return 0;
}
应用场景
命令模式,在实际项目中应用比较少见。本人见过其他同事在GUI 系统使用过。大致的项目背景如下, 点击界面上的按钮,对某数据进行修改、删除、新增使用了命令模式。
参考资料
《Head First 设计模式》第6章 命令模式