餐馆那些事之:Command Pattern

1. 概述
Composite Pattern是一种非常优雅的模式,实际使用中出现频率相当高。其通过对请求进行封装,解除了请求的发布者和具体实现者之间的耦合关系。
类图:

Customer:命令的发布者
Command:命令的接口
Concreate_command:具体命令的实现
Worker:命令的具体执行者

2. 实例
一个顾客跑到餐馆吃饭,他告诉服务员需要点的菜,服务员整理顾客的需要,然后告诉厨师,厨师负责具体做菜
对应上面的类图
Customer:顾客
Concrete_command:服务员
Worker:厨师
顾客和厨师解耦,顾客不需要关心具体哪个厨师在给他做菜,这就是command模式的好处之一。
实现代码如下:
#include <iostream>
using namespace std;

//厨师,具体的worker
class Cooker
{
public:
        void Do()
        {
                cout << "cooker cook" << endl;
        };
};

//command接口
class Command
{
public:
        virtual ~Command()
        {
        }

        virtual void Do() = 0;
};

//concrete_command
class Waiter: public Command
{
public:
        Waiter(Cooker* cooker)
        {
                _cooker = cooker;
        }

        virtual void Do()
        {
                _cooker->Do();
        }

private:
        //命令的执行者
        Cooker* _cooker;
};

//命令的发起者
class Customer
{
public:
        Customer(Command* command)
        {
                _command = command;
        }

        void order()
        {
                cout << "customer order" << endl;
                _command->Do();
        }
private:

        Command* _command;
};

int main()
{
        //命令的执行者
        Cooker cooker;

        //命令的封装
        Command* command = new Waiter(&cooker);

        //命令的发起者
        Customer customer(command);

        //执行命令
        customer.order();

        if(command)
        {
                delete command;
        }

        return 0;
}

输出:
$ ./bin/test       
customer order
cooker cook

3. undo
do操作完成了客户的需要,而undo操作则需要表示客户“后悔了”。undo操作使用非常多,常用的软件里面基本上都有undo的实现,使用undo,只要在command命令增加undo的接口,同时,concrete_command需要保存do之前的状态。
提供给客户取消订单的操作。
代码:
#include <iostream>
using namespace std;


class Cooker
{
public:
        Cooker()
        {
                _value = 0;
        }

        void Do()
        {
                _value++;
                cout << "cooker do"  <<  endl;
        };
        
        //标记值
        void value()
        {
                cout << "value=" << _value <<  endl;
        };

private:
        int _value;
};

class Command
{
public:
        virtual ~Command()
        {
        }

        virtual void Do() = 0;
        virtual void unDo() = 0;
};


class Waiter: public Command
{
public:
        Waiter(Cooker* cooker)
        {
                _cooker = cooker;
                _bak_cooker = new Cooker;
        }

        ~Waiter()
        {
                if(_bak_cooker)
                {
                        delete _bak_cooker;
                        _bak_cooker = NULL;
                }
        }

        virtual void Do()
        {
                cout << "waiter do" << endl;
                //保留状态
                *_bak_cooker = *_cooker;
                _cooker->Do();
        }

        //取消操作
        virtual void unDo()
        {
                cout << "waiter undo" << endl;
                //恢复状态
                *_cooker = *_bak_cooker;
        }

private:
        Cooker* _cooker;
        Cooker* _bak_cooker;
};

class Customer
{
public:
        Customer(Command* command)
        {
                _command = command;
        }

        void order()
        {
                cout << "customer order" << endl;
                _command->Do();
        }

        void unDo()
        {
                cout << "customer cancel rder" << endl;
                _command->unDo();
        }
private:

        Command* _command;
};

int main()
{
        Cooker cooker;
        Command* command = new Waiter(&cooker);
        Customer customer(command);

        customer.order();
        cooker.value();

        customer.unDo();
        cooker.value();

        if(command)
        {
                delete command;
        }

        return 0;
}
输出:
$ ./bin/test
customer order
waiter do
cooker do
value=1
customer cancel rder
waiter undo
value=0


  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值