这命令模式
- 一、概述
- 二、结构
- 三、实例
- 四、适用场景
- 五、优缺点
一、概述
描述:看电视时,只需要轻轻一按遥控器就能完成频道的切换,这就是命令模式,将换台请求和换台处理完全解耦了。电视机遥控器(命令发送者)通过按钮(具体命令)来遥控电视机(命令接收者)。
定义:命令是一种行为设计模式,它可将请求转换为一个包含与请求相关的所有信息的独立对象。该转换让你能根据不同的请求将方法参数化、延迟请求执行或将其放入队列中,且能实现可撤销操作
二、结构
- 发送者(Sender)——亦称“触发者(Invoker)”——类负责对请求进行初始化,其中必须包含一个成员变量来存储对于命令对象的引用。发送者触发命令,而不向接收者直接发送请求。注意,发送者并不负责创建命令对象:它通常会通过构造函数从客户端处获得预先生成的命令。
- 命令(Command)接口通常仅声明一个执行命令的方法。
- 具体命令(Concrete Commands)会实现各种类型的请求。具体命令自身并不完成工作,而是会将调用委派给一个业务逻辑对象。但为了简化代码,这些类可以进行合并。接收对象执行方法所需的参数可以声明为具体命令的成员变量。你可以将命令对象设为不可变,仅允许通过构造函数对这些成员变量进行初始化。
- 接收者(Receiver)类包含部分业务逻辑。几乎任何对象都可以作为接收者。绝大部分命令只处理如何将请求传递到接收者的细节,接收者自己会完成实际的工作。
-
- 客户端(Client)会创建并配置具体命令对象。客户端必须将包括接收者实体在内的所有请求参数传递给命令的构造函数。此后,生成的命令就可以与一个或多个发送者相关联了。
三、实例
#include<iostream>
#include<string>
#include<memory>
using namespace std;// 命令接口, C++中为抽象基类
class Command {
public:virtual void execute() = 0;
};// 具体命令类: 打开电视
class TVOpenCommand :public Command {
private:shared_ptr<Television> tv_;
public:explicit TVOpenCommand(shared_ptr<Television> tv):tv_(tv){}void execute() {tv_->open();}
};// 具体命令类: 关闭电视
class TVCloseCommand : public Command {
private:shared_ptr<Television> tv_;
public:explicit TVCloseCommand(std::shared_ptr<Television> tv) : tv_(tv) {}void execute() {tv_->close();}
};// 具体命令类: 切换频道
class TVChangeCommand : public Command {
private:shared_ptr<Television> tv_;public:explicit TVChangeCommand(std::shared_ptr<Television> tv) : tv_(tv) {}void execute() {tv_->changeChannel();}};// 触发者: 遥控器
class Controller
{
private:shared_ptr<Command> cmd_;
public:Controller() {}// 设置命令void setCommand(shared_ptr<Command> cmd) {cmd_ = cmd;}// 执行命令void executeCommand() {cmd_->execute();}
};// 接受者: 电视
class Television {
public:void open() {cout << "打开电视机!" << endl;}void close() {cout << "关闭电视机!" << endl;}void changeChannel() {cout << "切换电视频道!" << endl;}
};int main()
{// 接收者: 电视机Television *tv = new Television();shared_ptr<Television> tv = make_shared<Television>();//命令shared_ptr<Command> openCommand = make_shared<TVOpenCommand>(tv);shared_ptr<Command> closeCommand = make_shared<TVCloseCommand>(tv);shared_ptr<Command> changeCommand = make_shared<TVChangeCommand>(tv);//调用者:遥控器shared_ptr<Controller> controller = make_shared<Controller>();//测试controller->setCommand(openCommand);controller->executeCommand();controller->setCommand(closeCommand);controller->executeCommand();controller->setCommand(changeCommand);controller->executeCommand();}
四、适用场景
- 需要通过操作来参数化对象,可使用命令模式。
- 想要将操作放入队列中、操作的执行或者远程执行操作,可使用命令模式。
- 想要实现操作回滚功能,可使用命令模式。
五、优缺点
优点:
- 单一职责原则,可以解耦触发和执行操作的类。
- 开闭原则。你可以在不修改已有客户端代码的情况下在程序中创建新的命令。
- 可以实现撤销和恢复功能。
- 实现操作的延迟执行。
- 将一组简单命令组合成一个复杂命令。
缺点:
命令很多,增加系统复杂性。