《C++新经典设计模式》之第9章 命令模式

《C++新经典设计模式》之第9章 命令模式

命令模式.cpp
#include <iostream>
#include <list>
#include <memory>
using namespace std;

// 5种角色
// Receiver(接收者),Cook,提供请求业务的处理接口
// Invoker(调用者),Waiter,发送请求,通过命令对象执行请求
// Command(抽象命令),声明执行操作的接口
// ConcreteCommand(具体命令),通过调用Receiver相关操作执行请求
// Client(客户端),创建具体命令并设定接收者,创建调用者并驱动执行命令动作

// 将请求或命令封装为对象,通过参数进行传递,对象化的对象可以排队执行或者撤销

namespace ns1
{
    class Cook // 厨师类
    {
    public:
        void cook_fish() { cout << "fish" << endl; } // 做红烧鱼
        void cook_meat() { cout << "meat" << endl; } // 做锅包肉
    };

    class Command // 厨师做的每样菜品对应的抽象类
    {
    protected:
        shared_ptr<Cook> m_pcook;

    public:
        Command(const shared_ptr<Cook> &pcook) : m_pcook(pcook) {}
        virtual ~Command() {}
        virtual void Execute() = 0;
    };

    class CommandFish : public Command // 做红烧鱼菜品命令(顾客下的红烧鱼菜品便签)
    {
    public:
        CommandFish(const shared_ptr<Cook> &pcook) : Command(pcook) {}
        void Execute() override { m_pcook->cook_fish(); }
    };

    class CommandMeat : public Command // 做锅包肉菜品命令(顾客下的锅包肉菜品便签)
    {
    public:
        CommandMeat(const shared_ptr<Cook> &pcook) : Command(pcook) {}
        void Execute() override { m_pcook->cook_meat(); }
    };

    class Waiter0 // 服务员类
    {
        shared_ptr<Command> m_pcommand; // 服务员手中握着顾客书写的菜品便签
    public:
        void SetCommand(const shared_ptr<Command> &pcommand) { m_pcommand = pcommand; } // 顾客将便签交给服务员
        void Notify() { m_pcommand->Execute(); }                                        // 服务员将便签交到厨师手里让厨师开始做菜
    };

    class Waiter
    {
    private:
        // 一个便签中可以包含多个菜品甚至可以一次收集多个顾客的便签,达到一次性通知厨师做多道菜的效果
        list<shared_ptr<Command>> m_commlist; // 菜品列表,每道菜品作为一项,如果一个便签中有多个菜品,则这里将包含多项
    public:
        // 将顾客的便签增加到便签列表中,即便一个便签中包含多道菜品,这也相当于一道一道菜品加入到列表中
        void AddCommand(const shared_ptr<Command> &pcommand)
        {
            m_commlist.push_back(pcommand);
        }
        void DelCommand(const shared_ptr<Command> &pcommand) // 如果顾客想撤单则将便签从列表中删除
        {
            m_commlist.remove(pcommand);
        }
        void Notify() // 服务员将所有便签一次性交到厨师手里让厨师开始按顺序做菜
        {
            for (auto iter = m_commlist.cbegin(); iter != m_commlist.cend(); ++iter) // 依次让厨师做每一道菜品
                (*iter)->Execute();
        }
    };
}

namespace ns2
{
    class Cook // 厨师类
    {
    public:
        void cook_fish() { cout << "fish" << endl; } // 做红烧鱼
        void cook_meat() { cout << "meat" << endl; } // 做锅包肉
    };

    class Command // 厨师做的每样菜品对应的抽象类
    {
    protected:
        shared_ptr<Cook> m_pcook;

    public:
        Command(const shared_ptr<Cook> &pcook) : m_pcook(pcook) {}
        virtual ~Command() {}
        virtual void Execute() = 0;
    };

    class CommandFish : public Command // 做红烧鱼菜品命令(顾客下的红烧鱼菜品便签)
    {
    public:
        CommandFish(const shared_ptr<Cook> &pcook) : Command(pcook) {}
        void Execute() override { m_pcook->cook_fish(); }
    };

    class CommandMeat : public Command // 做锅包肉菜品命令(顾客下的锅包肉菜品便签)
    {
    public:
        CommandMeat(const shared_ptr<Cook> &pcook) : Command(pcook) {}
        void Execute() override { m_pcook->cook_meat(); }
    };

    class Traineewaiter // 实习服务员类
    {
        shared_ptr<Command> m_pcommand; // 实习服务员手中握着顾客书写的菜品便签
    public:
        Traineewaiter(const shared_ptr<Command> &pcommand) : m_pcommand(pcommand) {}
        void Notify() // 实习服务员将便签交到厨师手里让厨师开始做菜
        {
            if (m_pcommand != nullptr)
                m_pcommand->Execute();
        }
    };
}

namespace ns3
{
    class Cook // 厨师类
    {
    public:
        void cook_fish() { cout << "fish" << endl; } // 做红烧鱼
        void cook_meat() { cout << "meat" << endl; } // 做锅包肉
    };

    class Command // 厨师做的每样菜品对应的抽象类
    {
    protected:
        shared_ptr<Cook> m_pcook;

    public:
        Command(const shared_ptr<Cook> &pcook = nullptr) : m_pcook(pcook) {}
        virtual ~Command() {}
        virtual void Execute() = 0;
    };

    class CommandFish : public Command // 做红烧鱼菜品命令(顾客下的红烧鱼菜品便签
    {
    public:
        CommandFish(const shared_ptr<Cook> &pcook = nullptr) : Command(pcook) {}
        void Execute() override
        {
            if (m_pcook != nullptr)
                m_pcook->cook_fish();
        }
    };

    class CommandMeat : public Command // 做锅包肉菜品命令(顾客下的锅包肉菜品便签)
    {
    public:
        CommandMeat(const shared_ptr<Cook> &pcook = nullptr) : Command(pcook) {}
        void Execute() override
        {
            if (m_pcook != nullptr)
                m_pcook->cook_meat();
        }
    };

    class CommandMacro : public Command // 宏命令:把多个命令组合
    {
        list<shared_ptr<Command>> m_commlist;

    public:
        void AddCommand(const shared_ptr<Command> &pcommand)
        {
            m_commlist.push_back(pcommand);
        }
        virtual void Execute()
        {
            for (auto iter = m_commlist.cbegin(); iter != m_commlist.cend(); ++iter)
                (*iter)->Execute();
        }
    };

    class Traineewaiter // 实习服务员类
    {
        shared_ptr<Command> m_pcommand; // 实习服务员手中握着顾客书写的菜品便签
    public:
        Traineewaiter(const shared_ptr<Command> &pcommand = nullptr) : m_pcommand(pcommand) {}
        void Notify() // 实习服务员将便签交到厨师手里让厨师开始做菜
        {
            if (m_pcommand != nullptr)
                m_pcommand->Execute();
        }
    };
}

namespace ns4
{
    class TC
    {
    public:
        void operator()(int tv)
        {
            cout << "TC::operator(int tv), tv=" << tv << endl;
        }

    public:
        int operator()(int tv1, int tv2)
        {
            cout << "TC::operator(int tv1, int tv2), tv1=" << tv1 << ", tv2=" << tv2 << endl;
            return tv1 + tv2;
        }
    };

    template <class T>          // T代表可调用对象的类型
    void functmptest(T callobj) // callobj是个可调用对象
    {
        callobj(100);
    }
}

int main()
{
#if 0
    using namespace ns1;
    shared_ptr<Cook> pcook(new Cook());
    pcook->cook_fish();
    pcook->cook_meat();
#endif

#if 0
    using namespace ns1;
    shared_ptr<Cook> cook(new Cook());

    shared_ptr<Command> pcmd1(new CommandFish(cook));
    pcmd1->Execute(); // 做红烧鱼

    shared_ptr<Command> pcmd2(new CommandMeat(cook));
    pcmd2->Execute(); // 做锅包肉
#endif

#if 0
    using namespace ns1;
    shared_ptr<Cook> cook(new Cook());
    shared_ptr<Command> pcmd1(new CommandFish(cook));
    shared_ptr<Command> pcmd2(new CommandMeat(cook));
    shared_ptr<Waiter0> pwaiter(new Waiter0());

    pwaiter->SetCommand(pcmd1);
    pwaiter->Notify(); // 做红烧鱼

    pwaiter->SetCommand(pcmd2);
    pwaiter->Notify(); // 做锅包肉
#endif

#if 0
    using namespace ns1;
    shared_ptr<Cook> cook(new Cook());
    shared_ptr<Command> pcmd1(new CommandFish(cook));
    shared_ptr<Command> pcmd2(new CommandMeat(cook));
    shared_ptr<Waiter> pwaiter(new Waiter());
    // 把多道菜品分别加入到菜品列表中
    pwaiter->AddCommand(pcmd1);
    pwaiter->AddCommand(pcmd2);
    // 服务员一次性通知厨师做多道菜
    pwaiter->Notify();
#endif

#if 0
    using namespace ns2;
    shared_ptr<Cook> cook(new Cook());
    shared_ptr<Command> pcmd1(new CommandFish(cook));
    shared_ptr<Command> pcmd2(new CommandMeat(cook));

    shared_ptr<Traineewaiter> pwaitersx1(new Traineewaiter(pcmd1));
    pwaitersx1->Notify(); // 做红烧鱼
    shared_ptr<Traineewaiter> pwaitersx2(new Traineewaiter(pcmd2));
    pwaitersx2->Notify(); // 做锅包肉
#endif

#if 0
    using namespace ns3;
    shared_ptr<Cook> cook(new Cook());
    shared_ptr<Command> pcmd1(new CommandFish(cook));
    shared_ptr<Command> pcmd2(new CommandMeat(cook));
    shared_ptr<CommandMacro> pcmd(new CommandMacro());
    shared_ptr<Traineewaiter> pwaiter(new Traineewaiter(pcmd));

    pcmd->AddCommand(pcmd1);
    pcmd->AddCommand(pcmd2);
    pwaiter->Notify();
#endif

#if 1
    using namespace ns4;
    TC tc;
    tc(20); // 调用的是()操作符,这就是个可调用对象。等价于tc.operator()(20);
    cout << tc(30, 50) << endl;
    functmptest(tc);
#endif

    cout << "Over!\n";
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: "C经典-设计模式"是一本非常重要的书籍,它详细介绍了23种常用的设计模式设计模式是指在软件开发中,经过实践证明有效的解决方案。这本书提供了大量的示例和实践案例,帮助读者理解并应用这些设计模式。 这本书的特点之一是提供了丰富的图示,通过图示直观地展示了设计模式的结构和关系。这对于理解和记忆设计模式非常有帮助。 这本书从简单到复杂地介绍了各种不同类型的设计模式,包括创建型、结构型和行为型设计模式。每种设计模式都包括了详细的定义、应用场景、解决方案和与其他模式的关系。这样的组织结构使得读者可以快速地了解并选择适合自己项目需求的设计模式。 "C经典-设计模式"还提供了大量的实例代码和案例分析,帮助读者更好地理解和应用设计模式。这些案例覆盖了各种不同的编程语言和开发环境,使得读者可以从不同的角度去理解设计模式。 总的来说,"C经典-设计模式"是一本极具价值的书籍,无论是对于初学者还是有经验的开发者都具有很大的帮助。通过学习和应用这些设计模式,读者可以提高软件开发的质量和效率,使得自己的代码更加灵活、可维护和可扩展。 ### 回答2: "C经典设计模式pdf" 是指《C++经典设计模式》这本书的电子版PDF文件。这本书是一本关于C++设计模式经典著作,对于C++开发者学习和应用设计模式非常有帮助。通过阅读这本书的PDF版本,可以更方便地学习和参考其中的内容。 该PDF文件包含了本书的全部内容,包括理论介绍、具体的设计模式实现案例和相关的示意图等。使用该PDF文件,可以将书籍随身携带,随时进行学习和查阅。无论是初学者还是经验丰富的开发者都可以通过研读该书,深入了解各种设计模式的原理和使用方法。 设计模式是一种解决常见软件设计问题的经验总结,它们提供了一套通用且可重复使用的解决方案。通过应用设计模式,我们可以使得我们的代码更加灵活、可扩展和易于维护。在C++开发中使用设计模式,不仅可以提升代码质量和性能,还可以提高开发效率和团队协作能力。 《C++经典设计模式》是一本深入浅出的教材,适合各个层次的C++开发者阅读。无论你是刚入门的初学者,还是已经有一定经验的开发者,都可以从书中学到很多有用的知识和技巧。通过阅读该书的PDF版,可以更便捷地学习和实践设计模式,提升自身的软件设计和编码能力。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值