命令模式 行为型模式之一

1.定义

        命令模式(Command Pattern)又叫动作模式或事务模式。指的是将一个请求封装成一个对象,使发出请求的责任和执行请求的责任分割开,然后可以使用不同的请求把客户端参数化,这样可以使得两者之间通过命令对象进行沟通,从而方便将命令对象进行储存、传递、调用、增加与管理。命令模式是一种对象行为型模式。

        命令模式就是对命令的封装,就是把一系列的操作写到一个方法中,然后供客户端调用就行了。主要的作用就是对请求发送者与接收者进行耦合,发送者与接收者之间没有直接引用关系,使得对象之间的调用关系更加灵活,发送请求的对象只需要知道如何发送请求,而不必知道如何完成请求。

2.组成结构

命令模式主要由以下几个部分组成:

  1. 抽象命令类(Command):命令的抽象类,类中对需要执行的命令进行声明,一般来说要对外公布一个execute方法用来执行命令。
  2. 具体命令类(Concrete Command):抽象命令类的具体实现子类,对抽象类中声明的方法进行实现。
  3. 调用类(Invoker):调用者,负责调用命令,执行命令功能的相关操作,是具体命令对象业务的真正实现者。
  4. 接受类(Receiver):接收者,负责接收命令并且执行命令,是请求的发送者,它通常拥有很多的命令对象,并通过访问命令对象来执行相关请求,它不直接访问接收者。

敲黑板:命令模式的核心是将一个请求封装成一个对象,注意是将请求封装成对象,而不是请求者或者是调用者。

3.示例代码

#include <iostream>
#include <string>
#include <vector>
#include <algorithm>
#include <iterator>

using namespace std;

// 接受者,作为最底层的调用
class Receiver
{
public:
    void BakeMutton()
    {
        cout << "烤羊肉" << endl;
    }

    void BakeChicken()
    {
        cout << "烤鸡翅" << endl;
    }
};

// 基类
class Command
{
public:
    Command(Receiver* pstReceiver) :m_pstReceiver(pstReceiver)
    {

    }
    virtual void Excute() = 0;

protected:
    Receiver* m_pstReceiver;
};

// 具体类,用于调用接收者
class ConcreteCommandA : public Command
{
public:
    ConcreteCommandA(Receiver* pstReceiver) :Command(pstReceiver)
    {

    }
    virtual void Excute()
    {
        cout << "ConcreteCommandA excuting......" << endl;
        m_pstReceiver->BakeMutton();
    }

};

// 具体类,用于调用接收者
class ConcreteCommandB : public Command
{
public:
    ConcreteCommandB(Receiver* pstReceiver) :Command(pstReceiver)
    {

    }
    virtual void Excute()
    {
        cout << "ConcreteCommandB excuting......" << endl;
        m_pstReceiver->BakeChicken();
    }
};

// 调用者,作为最上层,用于管理具体类的操作,从而对接收者增删
class Invoke
{
public:
    void Add(Command* pstCommand)
    {
        m_vecPstCommand.push_back(pstCommand);
    }
    void Remove(Command* pstCommand)
    {
        m_vecPstCommand.erase(find(m_vecPstCommand.begin(), m_vecPstCommand.end(), pstCommand));
    }
    void RemoveAll()
    {
        m_vecPstCommand.clear();
    }
    void Notify()
    {
        for (auto it = m_vecPstCommand.begin(); it != m_vecPstCommand.end(); ++it)
        {
            (*it)->Excute();
        }
    }

private:
    vector<Command*> m_vecPstCommand;
};

int main(int argc, char* argv[])
{
    Receiver* pstReceiver = new Receiver();
    Command* pstConcreteCommandA = new ConcreteCommandA(pstReceiver);
    Command* pstConcreteCommandB = new ConcreteCommandB(pstReceiver);
    Invoke* pstInvoke = new Invoke();

    pstInvoke->Add(pstConcreteCommandA);
    pstInvoke->Add(pstConcreteCommandA);
    pstInvoke->Add(pstConcreteCommandB);
    pstInvoke->Notify();
    cout << "------------------" << endl << endl;

    pstInvoke->Remove(pstConcreteCommandA);  //撤销操作
    pstInvoke->Remove(pstConcreteCommandB);
    pstInvoke->Notify();
    cout << "------------------" << endl << endl;

    return 0;
}

/**
ConcreteCommandA excuting......
烤羊肉
ConcreteCommandA excuting......
烤羊肉
ConcreteCommandB excuting......
烤鸡翅
------------------

ConcreteCommandA excuting......
烤羊肉
------------------
**/

4.引用

从零开始学设计模式(二十二):命令模式(Command Pattern) - 知乎 (zhihu.com)

C++之命令(Command)模式 (qq.com)

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值