zoukankan      html  css  js  c++  java
  • 命令模式(c++实现)

    命令模式

    模式定义

    命令模式(Command),将一个请求封装为一个对象,从而使你可用不同的请求对客户进行参数化;对请求排队或记录请求日志,以及支持可撤销的操作。

    模式动机

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

    UML类图

    源码实现

    • command.h
    #include "chef.h"
    
    class Command
    {
    public:
        Command(Chef* chef);
        virtual ~Command();
        virtual void ExcuteCmd();
    
    protected:
        Chef*   m_Chef;
    };
    
    • chef.h
    class Chef
    {
    public:
        Chef();
        void KungPaoChicken();
        void FishFlavoredShreddedPork();
        void BigPlateChicken();
    };
    
    • chef.cpp
    #include "chef.h"
    #include <iostream>
    Chef::Chef()
    {
    
    }
    
    void Chef::KungPaoChicken()
    {
        std::cout << "宫保鸡丁" << std::endl;
    }
    
    void Chef::FishFlavoredShreddedPork()
    {
        std::cout << "鱼香肉丝" << std::endl;
    }
    
    void Chef::BigPlateChicken()
    {
        std::cout << "大盘鸡" << std::endl;
    }
    
    
    • kungpaochickencmd.h
    #include "command.h"
    #include "chef.h"
    
    class KungPaoChickenCmd : public Command
    {
    public:
        KungPaoChickenCmd(Chef* chef);
        void ExcuteCmd() override;
    };
    
    • kungpaochickencmd.cpp
    #include "kungpaochickencmd.h"
    
    KungPaoChickenCmd::KungPaoChickenCmd(Chef* chef)
        :Command(chef)
    {
    
    }
    
    void KungPaoChickenCmd::ExcuteCmd()
    {
        m_Chef->KungPaoChicken();
    }
    
    • waiter.h
    #include <list>
    #include <command.h>
    
    class Waiter
    {
    public:
        Waiter();
        void AddCmd(Command* cmd);
        void DelCmd(Command* cmd);
        void Nodify();
    private:
        std::list<Command*>     m_CmdList;
    };
    
    • waiter.cpp
    #include "waiter.h"
    
    Waiter::Waiter()
    {
    
    }
    
    void Waiter::AddCmd(Command *cmd)
    {
        m_CmdList.push_back(cmd);
    }
    
    void Waiter::DelCmd(Command *cmd)
    {
        m_CmdList.remove(cmd);
    }
    
    void Waiter::Nodify()
    {
        for(auto cmd : m_CmdList)
        {
            if(cmd)
                cmd->ExcuteCmd();
        }
    }
    
    • main.cpp
    #include <iostream>
    #include "fishflavoredshreddedporkcmd.h"
    #include "kungpaochickencmd.h"
    #include "bigplatechickencmd.h"
    #include "waiter.h"
    #include <memory>
    int main()
    {
        Chef* chef = new Chef();
        Waiter waiter;
    
        std::shared_ptr<FishFlavoredShreddedPorkCmd> ffspc = std::make_shared<FishFlavoredShreddedPorkCmd>(chef);
        std::shared_ptr<KungPaoChickenCmd> kpcc = std::make_shared<KungPaoChickenCmd>(chef);
        std::shared_ptr<BigPlateChickenCmd> bpcc = std::make_shared<BigPlateChickenCmd>(chef);
    
        waiter.AddCmd(ffspc.get());
        waiter.AddCmd(kpcc.get());
        waiter.AddCmd(bpcc.get());
        //        waiter.DelCmd(kpcc.get);
    
        waiter.Nodify();
        return 0;
    }
    
    
    • 运行结果

    鱼香肉丝

    宫保鸡丁

    大盘鸡

    优点

    命令模式的优点

    • 它能较容易的设计一个命令队列;
    • 在需要的情况下,可以较容易的将命令计入日志;
    • 允许接收请求的一方决定是否要否决请求;
    • 可以容易的实现对请求的撤销和重做;
    • 由于加进新的具体命令类不影响其他的类,因此增加新的具体命令类很容易;
    • 把请求一个操作的对象与知道怎么执行一个操作的对象分隔开;

    缺点

    模式的缺点

  • 相关阅读:
    vue 中简单路由的实现
    Vue中对生命周期的理解
    内存泄漏
    前端工程化
    exports 和 module.exports 的区别
    Nodejs的url模块方法
    MongoDB 的获取和安装
    Anjular JS 的一些运用
    移动端vconsole调试
    安装fiddler时,电脑浏览器没网
  • 原文地址:https://www.cnblogs.com/wzxNote/p/13305597.html
Copyright © 2011-2022 走看看