zoukankan      html  css  js  c++  java
  • 【设计模式】烤羊肉串引来的思考 命令模式

    一,概述

            定义:命令模式将一个请求或者操作封装到一个命令对象中。允许系统使用不同的请求将客户端参数化,对请求排队或者记录请求日志,提供命令的撤销,恢复能力

            优点:

    1 命令模式使新的命令很容易被加入

    2 允许接受请求方否决请求

    3 可较容易地设计一个命令队列

    4 可以实现对请求的Undo,Redo

    5 可以将命令计入日志

    二,示例

            两个人 去吃烧烤,先路过一个烧烤摊,人多管理比较混乱,命令请求者跟命令实施者“紧耦合”。

            人太对,没吃,然后去烧烤店,遇到了经典的命令模式:服务生负责记录命令,传递命令。厨师负责执行命令。顾客则发出命令

           1)烧烤摊代码

    #include <iostream>
    using namespace std;
     
    
        //烤肉串者
    class Barbecuer
    {
            //烤羊肉
            public:
    		 void BakeMutton()
            {
                cout<<"烤羊肉串!"<<endl;
            }
            //烤鸡翅
    		 void BakeChickenWing()
            {
                cout<<"烤鸡翅!"<<endl;
            }
    }; 
    int main()
    {
                Barbecuer *boy = new Barbecuer();
    
                boy->BakeMutton();
                boy->BakeMutton();
                boy->BakeMutton();
                boy->BakeChickenWing();
                boy->BakeMutton();
                boy->BakeMutton();
                boy->BakeChickenWing();
    
               
    }

        2)烧烤店(第一版)

             缺点:客户点一个菜,服务员通知一下(不符合实际)。应该点菜完成后一次性通知

                         如果某一个菜没有了,不应该客户判断,应该服务员判断

                         客户点菜需要记录日志,以备结账使用。

                         

    #include <iostream>
    using namespace std;
     
        //烤肉串者
        class Barbecuer//命令执行者 
        {
            public:
    		 void BakeMutton()
            {
                cout<<"烤羊肉串!"<<endl;
            }
    
            void BakeChickenWing()
            {
                cout<<"烤鸡翅!"<<endl;
            }
        }; 
         //抽象命令
         class Command//声明执行的接口 
        {
            protected:
    		 Barbecuer *receiver;
    
            public:
    		 Command(Barbecuer *receiver)
            {
                this->receiver = receiver;
            }
    
            //执行命令
            virtual void ExcuteCommand()=0;
        }; 
        
       //服务员
        class Waiter //Invoker类 
        {
            private:
    		 Command *command;
    
            //设置订单
            public: 
    		 void SetOrder(Command *command)
            {
                this->command = command;
            }
            //通知执行
            void Notify()
            {
                command->ExcuteCommand();
            }
        }; 
    
       
    
        //烤羊肉串命令
        class BakeMuttonCommand :public Command
        {
            public: 
    		 BakeMuttonCommand(Barbecuer *receiver)
                : Command(receiver)
            { }
    
             void ExcuteCommand()
            {
                receiver->BakeMutton();
            }
        }; 
    
        //烤鸡翅命令
        class BakeChickenWingCommand :public Command
        {
            public:
    		 BakeChickenWingCommand(Barbecuer *receiver)
                : Command(receiver)
            { }
    
            void ExcuteCommand()
            {
                receiver->BakeChickenWing();
            }
        }; 
    
    
        
             int main()
            {
                //开店前的准备
                Barbecuer *boy = new Barbecuer();
                Command *bakeMuttonCommand1 = new BakeMuttonCommand(boy);// 烤羊肉 
                Command *bakeMuttonCommand2 = new BakeMuttonCommand(boy);
                Command *bakeChickenWingCommand1 = new BakeChickenWingCommand(boy);//烤鸡翅 
                Waiter *girl = new Waiter();
    
                //开门营业
                girl->SetOrder(bakeMuttonCommand1);
                girl->Notify();
                girl->SetOrder(bakeMuttonCommand2);
                girl->Notify();
                girl->SetOrder(bakeChickenWingCommand1);
                girl->Notify();       
    
            }

       3)烧烤店(松耦合升级版)(C#)

    static void Main(string[] args)
            {
                //开店前的准备
                Barbecuer boy = new Barbecuer();
                Command bakeMuttonCommand1 = new BakeMuttonCommand(boy);
                Command bakeMuttonCommand2 = new BakeMuttonCommand(boy);
                Command bakeChickenWingCommand1 = new BakeChickenWingCommand(boy);
                Waiter girl = new Waiter();
    
                //开门营业 顾客点菜
                girl.SetOrder(bakeMuttonCommand1);
                girl.SetOrder(bakeMuttonCommand2);
                girl.SetOrder(bakeChickenWingCommand1);
    
                //点菜完闭,通知厨房
                girl.Notify();
    
                Console.Read();
    
            }
        }
    
        //服务员
        public class Waiter
        {
            private IList<Command> orders = new List<Command>();
    
            //设置订单
            public void SetOrder(Command command)
            {
                if (command.ToString() == "命令模式.BakeChickenWingCommand")
                {
                    Console.WriteLine("服务员:鸡翅没有了,请点别的烧烤。");
                }
                else
                {
                    orders.Add(command);
                    Console.WriteLine("增加订单:" + command.ToString() + "  时间:" + DateTime.Now.ToString());
                }
            }
    
            //取消订单
            public void CancelOrder(Command command)
            {
                orders.Remove(command);
                Console.WriteLine("取消订单:" + command.ToString() + "  时间:" + DateTime.Now.ToString());
            }
    
            //通知全部执行
            public void Notify()
            {
                foreach (Command cmd in orders)
                {
                    cmd.ExcuteCommand();
                }
            }
        }
    
        //抽象命令
        public abstract class Command
        {
            protected Barbecuer receiver;
    
            public Command(Barbecuer receiver)
            {
                this.receiver = receiver;
            }
    
            //执行命令
            abstract public void ExcuteCommand();
        }
    
        //烤羊肉串命令
        class BakeMuttonCommand : Command
        {
            public BakeMuttonCommand(Barbecuer receiver)
                : base(receiver)
            { }
    
            public override void ExcuteCommand()
            {
                receiver.BakeMutton();
            }
        }
    
        //烤鸡翅命令
        class BakeChickenWingCommand : Command
        {
            public BakeChickenWingCommand(Barbecuer receiver)
                : base(receiver)
            { }
    
            public override void ExcuteCommand()
            {
                receiver.BakeChickenWing();
            }
        }
    
        //烤肉串者
        public class Barbecuer
        {
            public void BakeMutton()
            {
                Console.WriteLine("烤羊肉串!");
            }
    
            public void BakeChickenWing()
            {
                Console.WriteLine("烤鸡翅!");
            }
        }
    




    三,命令模式基本代码构成


    #include <iostream>
    using namespace std;
     
     class Receiver//执行命令类 
     {
     public:
     	void Action()
      	{
       		cout<<"执行请求!"<<endl;
      	}
     }; 
     class Command //声明执行操作的接口 
     {
     protected: 
     		Receiver *receiver;
    
    public:
    		Command(Receiver *receiver)
            {
                this->receiver = receiver;
            }
    
            virtual  void Execute()=0;
    }; 
        
    
    class Invoker//要求该命令执行这个请求 
    {
            private:
    		     Command *command;
    
            public:
    	    void SetCommand(Command *command)
                {
                      this->command = command;
                }
    
            void ExecuteCommand()
            {
                command->Execute();
            }
    }; 
    
    
    class ConcreteCommand :public Command //将一个接收者对象绑定于一个动作 
    {
    public:
    	ConcreteCommand(Receiver *receiver):Command(receiver) 
    	{ }
    
    	void Execute()      //实现命令接口 
     	{
      		receiver->Action();
      	}
    }; 
    
    int main()
    {
    	Receiver *r = new Receiver();//命令的真正执行类 (后台厨师) 
    	Command *c = new ConcreteCommand(r);//将命令绑定到 命令执行者 (顾客) 
    	Invoker *i = new Invoker();//要求命令执行者执行命令(记账单的小生) 
    
    	// Set and execute command 
    	i->SetCommand(c);
    	i->ExecuteCommand();
    
    	system("pause"); 
    } 


  • 相关阅读:
    windows server 2008服务器 做raid0
    SQL Server 2012将数据库备份到网络中的共享文件夹
    SQL Server 2012 使用警报调度数据库作业通知操作员
    Cent OS7上安装并初始化MySQL8.0.15
    nginx 跨域请求、别名路径及防盗链的配置
    ElasticSearch和Kibanna的安装与启动
    Mybatis报错:Result Maps collection already contains value for xx.xxx
    Redis的常见数据类型——String类型
    Redis安装与配置
    nginx日志切割(手动/自动)
  • 原文地址:https://www.cnblogs.com/secbook/p/2654973.html
Copyright © 2011-2022 走看看