定義
命令模式將“請求”封裝成對象,以便使用不同的請求、隊列或者日誌來參數化其他對象。命令模式也支持可撤銷的操作。
本文僅介紹將“請求”封裝成對象,以便使用不同的請求。
定義命令模式類圖
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章 命令模式