Published on

设计模式(14)——命令 Command

Authors
  • avatar
    Name
    Leon
    Twitter

十四、Command(命令模式,别名 Action 动作,Transaction 事务,对象行为型模式)

1. 意图:

  将一个请求封装为一个对象,从而使你可用不同的请求对客户进行参数化;对请求排队或记录请求日志,以及支持可撤消的操作。

2. 适用:

  1. 抽象出待执行的动作以参数化某对象。
  2. 在不同的时刻指定、排列和执行请求。
  3. 支持取消操作。
  4. 支持修改日志。
  5. 用构建在原语操作上的高层操作构造一个系统。

3. 类图:

4. 中间层思考:

  命令模式在界面组件和功能模块之间提供了一个中间层 Command,界面组件不再直接调用功能模块,而是调用 Command 的抽象方法。这样将界面组件与功能模块解耦,界面组件可以灵活切换要实现的功能,功能模块的改动也不会对界面组件有影响。

5. 命令模式与适配器模式

  命令模式的类图和适配器模式的类图很像,它们做的事情都是制造了一个中间层, 提供给系统统一的调用接口,封装了真正干活的实体。它们的差异还是在于使用意图,命令模式是为了命令的复用和灵活切换,而适配器模式是为了在新旧接口之间做兼容。

6. C++实现:

  1. 首先编写一个命令接口 Command,包含一个执行方法 Excute()
  2. 编写一个接收者类 Receiver,包含一个具体的执行动作方法 Action()
  3. 编写命令接口的具体的实现类 ConcreteCommandhas-a 一个接收者对象 _rev,由ConcreteCommand的构造函数初始化
  4. 编写调用者类 Invokerhas-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;
}