命令模式

  1. Command(抽象命令类):抽象出命令对象,可以根据不同的命令类型。写出不同的实现类

  2. Concrete Command(具体命令类):实现了抽象命令对象的具体实现

  3. Invoker(调用者/请求者):请求的发送者,它通过命令对象来执行请求。一个调用者并不需要在设计时确定其接收者,因此它只与抽象命令来之间存在关联。在程序运行时,将调用命令对象的execute() ,间接调用接收者的相关操作。

  4. Receiver(接收者):接收者执行与请求相关的操作,真正执行命令的对象。具体实现对请求的业务处理。未抽象前,实际执行操作内容的对象。

  5. Client(客户端):在客户类中需要创建调用者对象,具体命令类对象,在创建具体命令对象时指定对应的接收者。发送者和接收者之间没有之间关系。都通过命令对象来调用。

示例:

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

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 (vector<Command*>::iterator it = m_vecPstCommand.begin(); it != m_vecPstCommand.end(); ++it)
        //for (typeof(m_vecPstCommand.begin()) 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;

    getchar();
    return 0;
}

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

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

输出:

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

ConcreteCommandA excuting......
烤羊肉
------------------




参考:

https://www.guyuehome.com/37989

posted @   double64  阅读(24)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· DeepSeek 开源周回顾「GitHub 热点速览」
· 记一次.NET内存居高不下排查解决与启示
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
点击右上角即可分享
微信分享提示