设计模式-命令模式

命令模式

模式定义

  • 命令模式是一种行为定义模式,可以将请求转换成一个与请求相关的,包含该请求所有信息的独立对象,并且能够根据不同请求将方法参数化,延迟请求执行或者将其放入到队列中且能实现撤销等操作

模式动机

  • 敏捷开发的原则要求,不要在代码上添加基于猜测的,实际上不需要的功能。如果不清楚一个系统是否需要命令模式,一般不要急着去实现它,事实上,在需要的时候通过重构实现这个模式并不难,只有在真正需要撤销/恢复操作功能的时候,将原有的代码重构为命令才合适

UML 类图

代码实例

#include <iostream>
#include <vector>
#include <algorithm>
#include <iterator>
#include <string>
using namespace std;

class Receiver
{
public:
    void BakeMutton(){
        cout << "Bake mutton..." << endl;
    }
    void BakeChicken(){
        cout << "Bake chicken..." << endl;
    }
};

class Command
{
public:
    Command(Receiver* pstRecevier):m_pstReceiver(pstRecevier){}
    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(typeof(m_vecPstCommand.begin()) it = m_vecPstCommand.begin(); it != m_vecPstCommand.end(); it++){
            (*it)->Excute();
        }
    }
private:
    vector<Command*> m_vecPstCommand;
};

int main()
{
    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 << "-----------First Call End---------" << endl;

    pstInvoke->Remove(pstConcreteCommandA);
    pstInvoke->Remove(pstConcreteCommandB);
    pstInvoke->Notify();

    cout << "-----------Second Call End---------" << endl;

}

优缺点

优点:

  1. 类间解耦,调用者和接收者没有没有直接耦合,调用这只需要调用 Command 的方法执行接收者的业务逻辑即可
  2. 可扩展性,如果 Command 需要扩展,只需要新增一个子类即可

缺点

  1. 如果命令很多,则意味着 Command 子类很多,增加了系统的复杂性
posted @ 2023-08-26 14:36  王清河  阅读(8)  评论(0编辑  收藏  举报