- Published on
设计模式(14)——命令 Command
- Authors
- Name
- Leon
十四、Command(命令模式,别名 Action 动作,Transaction 事务,对象行为型模式)
1. 意图:
将一个请求封装为一个对象,从而使你可用不同的请求对客户进行参数化;对请求排队或记录请求日志,以及支持可撤消的操作。
2. 适用:
- 抽象出待执行的动作以参数化某对象。
- 在不同的时刻指定、排列和执行请求。
- 支持取消操作。
- 支持修改日志。
- 用构建在原语操作上的高层操作构造一个系统。
3. 类图:
4. 中间层思考:
命令模式在界面组件和功能模块之间提供了一个中间层 Command
,界面组件不再直接调用功能模块,而是调用 Command 的抽象方法。这样将界面组件与功能模块解耦,界面组件可以灵活切换要实现的功能,功能模块的改动也不会对界面组件有影响。
5. 命令模式与适配器模式
命令模式的类图和适配器模式的类图很像,它们做的事情都是制造了一个中间层, 提供给系统统一的调用接口,封装了真正干活的实体。它们的差异还是在于使用意图,命令模式是为了命令的复用和灵活切换,而适配器模式是为了在新旧接口之间做兼容。
6. C++实现:
- 首先编写一个命令接口
Command
,包含一个执行方法Excute()
- 编写一个接收者类
Receiver
,包含一个具体的执行动作方法Action()
- 编写命令接口的具体的实现类
ConcreteCommand
,has-a
一个接收者对象_rev
,由ConcreteCommand的构造函数初始化 - 编写调用者类
Invoker
,has-a
一个命令对象_cmd
,包含一个调用方法Invoke()
,方法体调用 _cmd 的 Excute(),Exuete() 执行具体接收者如 _rev 的 Action()
Command.h
//Command.h
#pragma once
class Receiver;
class Command {
public:
virtual ~Command();
virtual void Excute() = 0;
protected:
Command();
private:
};
class ConcreteCommand : public Command {
public:
ConcreteCommand(Receiver* rev);
~ConcreteCommand();
void Excute();
protected:
private:
Receiver* _rev;
};
Command.cpp
//Command.cpp
#include "Command.h"
#include "Receiver.h"
#include <iostream>
ConcreteCommand::ConcreteCommand(Receiver * rev){
this->_rev = rev;
}
ConcreteCommand::~ConcreteCommand(){
delete _rev;
}
void ConcreteCommand::Excute(){
this->_rev->Action();
}
Command::~Command(){}
Command::Command(){}
Invoker.h
//Invoker.h
#pragma once
class Command;
class Invoker {
public:
Invoker(Command* cmd);
~Invoker();
void Invoke();
protected:
private:
Command* _cmd;
};
Invoker.cpp
//Invoker.cpp
#include "Invoker.h"
#include "Command.h"
Invoker::Invoker(Command * cmd){
this->_cmd = cmd;
}
Invoker::~Invoker(){
delete _cmd;
}
void Invoker::Invoke()
{
this->_cmd->Excute();
}
Receiver.h
//Receiver.h
#pragma once
class Receiver {
public:
Receiver();
~Receiver();
void Action();
protected:
private:
};
Receiver.cpp
//Receiver.cpp
#include "Receiver.h"
#include <iostream>
Receiver::Receiver() {}
Receiver::~Receiver() {}
void Receiver::Action() {
std::cout << "Receiver action......" << std::endl;
}
main.cpp
//main.cpp
#include "Command.h"
#include "Invoker.h"
#include "Receiver.h"
#include <iostream>
using namespace::std;
int main(int argc, char* argv[]) {
Receiver* rev = new Receiver();
Command* cmd = new ConcreteCommand(rev);
Invoker* inv = new Invoker(cmd);
inv->Invoke();
return 0;
}