利用命令模式模拟烤肉店点餐 C++

81 篇文章 0 订阅
29 篇文章 1 订阅

1. 命令模式

将一个请求封装为一个对象,从而可用不同的请求对对象参数进行参数化, 对请求队列或记录请求日志, 以及支持可撤销操作等。
命令模式的优点:
1. 可以容易的设计一个命令队列
2. 在需要的情况下, 可以比较容易的将命令记入日志
3. 允许接收请求的一方决定是否接受命令
4. 可以很容易的实现对请求的撤销和重做
5. 可以很容易的添加新的命令类

敏捷开发中告诉我们, 不要伪代码添加基于猜测,或者实际不需要的功能, 如果不清楚一个系统是否需要命令模式, 一般不要急着实现它, 事实上, 在需要的时候通过重构来实现这个模式并不困难, 只有在真正需要如撤销或者恢复操作等功能的时候, 把原来的代码重构为命令模式才有意义

2. UML 图

这里写图片描述

3. 运行效果图

这里写图片描述

4. code

barbecur.h

#ifndef _BARBECUER_H_
#define _BARBECUER_H_

#include <iostream>
using std::cout;
using std::endl;

/************************************************************************/
/* 烤肉者                                                               */
/************************************************************************/
class CBarbecuer{
public:
    void BakeMutton(){ cout << "bake mutton" << endl; }
    void BakeChickenWing() { cout << "bake chicken wing" << endl; }
};

#endif // _BARBECUER_H_

command.h

#ifndef _COMMAND_H_
#define _COMMAND_H_

#include "Barbecuer.h"

/************************************************************************/
/* 传递的命令                                                           */
/************************************************************************/
class CCommand{
public:
    CCommand(CBarbecuer * barbecur){ this->barbecur = barbecur; }
    virtual void Excute() = 0;

protected:
    CBarbecuer * barbecur;
};

/************************************************************************/
/* 烤羊肉命令                                                           */
/************************************************************************/
class BakeMuttonCommand : public CCommand{
public:
    BakeMuttonCommand(CBarbecuer * barbecur) : CCommand(barbecur){}
    void Excute(){ barbecur->BakeMutton(); }
};

/************************************************************************/
/* 烤鸡翅命令                                                           */
/************************************************************************/
class BakeChickenWingCommand : public CCommand{
public:
    BakeChickenWingCommand(CBarbecuer * barbecur) : CCommand(barbecur){}
    void Excute(){ barbecur->BakeChickenWing(); }

};

#endif // _COMMAND_H_

waiter.h

#ifndef _WAITER_H_
#define _WAITER_H_

#include "command.h"
#include <list>
#include <algorithm>
#include <ctime>

using std::list;
using std::localtime;

/************************************************************************/
/* waiter 类                                                            */
/************************************************************************/
class CWaiter{
public:
    void setOrder(CCommand * cmd){
        if (typeid(*cmd) == typeid(BakeChickenWingCommand))
            cout << "没有鸡翅了" << endl;
        else{
            orders.push_front(cmd);
            time_t t = time(nullptr);
            cout << "增加订单: " << typeid(*cmd).name() << "\t" << std::asctime(localtime(&t));
        }
    }

    void cancelOrder(CCommand * cmd){
        for (auto iter = orders.begin(); iter != orders.end(); iter++){
            if (*iter == cmd){
                orders.erase(iter);
                time_t t = time(nullptr);
                cout << "取消订单: " << typeid(*cmd).name() << "\t" << std::asctime(localtime(&t));
                break;
            }
        }
    }

    void notify(){
        for_each(orders.begin(), orders.end(), [](CCommand * cmd){cmd->Excute(); });
    }

private:
    list<CCommand *> orders;
};

#endif // _WAITER_H_

main.cpp

#define _CRT_SECURE_NO_WARNINGS

#include "Barbecuer.h"
#include "command.h"
#include "waiter.h"
#include <iostream>

using namespace std;

int main(){
    CBarbecuer boy;
    CCommand * bake = new BakeMuttonCommand(&boy);
    CCommand * chick = new BakeChickenWingCommand(&boy);
    CWaiter girl;

    girl.setOrder(bake);
    girl.setOrder(chick);
    girl.setOrder(bake);

    girl.notify();

    system("pause");
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值