设计模式1 --- 命令模式

1. 命令模式介绍

1.1 定义

命令模式的英文翻译是 Command Design Pattern。在 GoF 的《设计模式》一书中,它是这么定义的:

The command pattern encapsulates a request as an object, thereby letting us parameterize other objects with different requests, queue or log requests, and support undoable operations.
  • 中文翻译为:

命令模式:将请求封装成对象,以便使用不同的请求、日志、队列等来参数化其他对象。命令模式也支持撤销操作。

  • 命令模式的本质:封装请求
  • 设计意图:命令模式通过将请求封装到一个命令(Command)对象中,实现了请求调用者和具体实现者之间的解耦。

1.2 应用场景

在需要事务的系统中,可以选用命令模式。命令模式提供了对事务进行建模的方法。命令模式有一个别名就是Transaction。
命令模式,类似于C语言里的回调函数。

1.3 命令模式的结构


命令模式涉及的角色及其职责如下:

  1. 抽象命令(Command):一般定义为接口,用来定义执行命令的接口。
  2. 具体命令(ConcreteCommand)角色:通常会持有接收者对象,并调用接收者对象的相应功能来完成命令要执行的操作。
  3. 接收者(Receiver)角色:真正执行命令的对象。任何类都可能成为接收者,只要它能够实现命令要求实现的相应功能。
  4. 调用者(Invoker)角色:要求命令对象执行请求,通常会持有命令对象,可以持有很多的命令对象。这个是客户端真正触发命令并要求命令执行相应操作的地方,也就是说相当于使用命令对象的入口。
  5. 客户端(Client)角色:创建具体的命令对象,并且设置命令对象的接收者。

2. 示例代码

以客人点餐为例,实现:点餐和cook隔离。

// CommandModel.h文件
#pragma once
#include 
#include 
#include 

// 烤肉师傅
class BarbecueMaster
{
public:
    void MakeMutton()
    {
        std::cout << "烤羊腿喽" << std::endl;
    }
    void MakeChiken()
    {
        std::cout << "烤鸡肉喽" << std::endl;
    }
};
// 命令类
class Command
{
protected:
    BarbecueMaster * m_master;
public:
    Command(BarbecueMaster * p)
    {
        m_master = p;
    }
    virtual void executeCmd() = 0;
};

// 命令1
class CommandMutton : public Command
{
public:
    CommandMutton(BarbecueMaster * p) : Command(p) {}
    void executeCmd()
    {
        m_master->MakeMutton();
    }
};

// 命令2
class CommandChiken : public Command
{
public:
    CommandChiken(BarbecueMaster * p) : Command(p) {}
    void executeCmd()
    {
        m_master->MakeChiken();
    }
};

// 服务员
class Waiter
{
private:
    std::vector m_vec;
public:
    ~Waiter()
    {
        for (auto it = m_vec.begin(); it != m_vec.end(); it++)
        {
            delete(*it);
        }
        m_vec.clear();
    }
    
    // Waiter Func1
    void add(Command * p)
    {
        m_vec.push_back(p);
    }
    
    // Waiter Func2
    void remove(Command * p)
    {
        auto it = find(m_vec.begin(), m_vec.end(), p);
        if (it != m_vec.end())
            m_vec.erase(it);
    }
    
    // Waiter Func3
    void submitCmd()
    {
        for (auto it = m_vec.cbegin(); it != m_vec.cend(); it++)
        {
            (*it)->executeCmd();
        }
    }
};

测试代码:

#include 
#include "CommandModel.h"

int main()
{
    using namespace std;
    // 命令模式
    Waiter * pWaiter = new Waiter();
    BarbecueMaster * pMaster = new BarbecueMaster();
    
    pWaiter->add(new CommandChiken(pMaster));
    pWaiter->add(new CommandMutton(pMaster));
    
    pWaiter->submitCmd();
    
    delete pMaster;
    delete pWaiter;

    getchar();
    return 0;
}

你可能感兴趣的:(设计模式)