zoukankan      html  css  js  c++  java
  • 设计模式(14)命令模式

    模式介绍

    命令模式将请求封装为对象,从而允许开发人员根据接收到该命令的类来不同地对待该请求。此外,它能够实现更复杂的体系结构,甚至可以实现诸如撤销/重做之类的操作。

    责任链模式非常适合命令模式,因为前者可以使用后者的对象来表示其请求。

    示例

    我们将建模一个系统,在该系统中,我们可以在快餐店创建订单,并使用命令模式进行订单添加、删除和修改。

    菜单:

    /// <summary>
    /// Represents an item being ordered from this restaurant.
    /// </summary>
    public class MenuItem
    {
        public string Name { get; set; }
        public int Amount { get; set; }
        public double Price { get; set; }
    
        public MenuItem(string name, int amount, double price)
        {
            Name = name;
            Amount = amount;
            Price = price;
        }
    
        public void Display()
        {
            Console.WriteLine("
    Name: " + Name);
            Console.WriteLine("Amount: " + Amount.ToString());
            Console.WriteLine("Price: $" + Price.ToString());
        }
    }
    

    顾客:

    /// <summary>
    /// The Invoker class
    /// </summary>
    public class Patron
    {
        private OrderCommand _orderCommand;
        private MenuItem _menuItem;
        private FastFoodOrder _order;
    
        public Patron()
        {
            _order = new FastFoodOrder();
        }
    
        public void SetCommand(int commandOption)
        {
            _orderCommand = new CommandFactory().GetCommand(commandOption);
        }
    
        public void SetMenuItem(MenuItem item)
        {
            _menuItem = item;
        }
    
        public void ExecuteCommand()
        {
            _order.ExecuteCommand(_orderCommand, _menuItem);
        }
    
        public void ShowCurrentOrder()
        {
            _order.ShowCurrentItems();
        }
    }
    
    public class CommandFactory
    {
        //Factory method
        public OrderCommand GetCommand(int commandOption)
        {
            switch (commandOption)
            {
                case 1:
                    return new AddCommand();
                case 2:
                    return new ModifyCommand();
                case 3:
                    return new RemoveCommand();
                default:
                    return new AddCommand();
            }
        }
    }
    

    抽象的命令类:

    /// <summary>
    /// The Command abstract class
    /// </summary>
    public abstract class OrderCommand
    {
        public abstract void Execute(List<MenuItem> order, MenuItem newItem);
    }
    

    具体的命令类:

    /// <summary>
    /// A concrete command
    /// </summary>
    public class AddCommand : OrderCommand
    {
        public override void Execute(List<MenuItem> currentItems, MenuItem newItem)
        {
            currentItems.Add(newItem);
        }
    }
    
    /// <summary>
    /// A concrete command
    /// </summary>
    public class RemoveCommand : OrderCommand
    {
        public override void Execute(List<MenuItem> currentItems, MenuItem newItem)
        {
            currentItems.Remove(currentItems.Where(x=>x.Name == newItem.Name).First());
        }
    }
    
    /// <summary>
    /// A concrete command
    /// </summary>
    public class ModifyCommand : OrderCommand
    {
        public override void Execute(List<MenuItem> currentItems, MenuItem newItem)
        {
            var item = currentItems.Where(x => x.Name == newItem.Name).First();
            item.Price = newItem.Price;
            item.Amount = newItem.Amount;
        }
    }
    

    客户端调用:

    static void Main(string[] args)
    {
        Patron patron = new Patron();
        patron.SetCommand(1 /*Add*/);
        patron.SetMenuItem(new MenuItem("French Fries", 2, 1.99));
        patron.ExecuteCommand();
    
        patron.SetCommand(1 /*Add*/);
        patron.SetMenuItem(new MenuItem("Hamburger", 2, 2.59));
        patron.ExecuteCommand();
    
        patron.SetCommand(1 /*Add*/);
        patron.SetMenuItem(new MenuItem("Drink", 2, 1.19));
        patron.ExecuteCommand();
    
        patron.ShowCurrentOrder();
    
        //Remove the french fries
        patron.SetCommand(3 /*Remove*/);
        patron.SetMenuItem(new MenuItem("French Fries", 2, 1.99));
        patron.ExecuteCommand();
    
        patron.ShowCurrentOrder();
    
        //Now we want 4 hamburgers rather than 2
        patron.SetCommand(2 /*Edit*/);
        patron.SetMenuItem(new MenuItem("Hamburger", 4, 2.59));
        patron.ExecuteCommand();
    
        patron.ShowCurrentOrder();
    
        Console.ReadKey();
    }
    

    总结

    命令设计模式试图将命令封装为对象,并允许不同的接收器根据接收器自己的设计来处理它们。

    源代码

    https://github.com/exceptionnotfound/DesignPatterns/tree/master/Command

    原文

    https://www.exceptionnotfound.net/command-the-daily-design-pattern/

  • 相关阅读:
    [C++] socket
    [C++] socket
    2014-3-16 星期天 晴[改变生活规律,稳中求进]
    [C++] socket
    [C++] socket
    [ACM_水题] Yet Another Story of Rock-paper-scissors [超水 剪刀石头布]
    easyui datagrid如何获取到每行的文本框
    JS传递数组到后台
    如何将js的object对象传到后台--->JavaScript之对象序列化
    EasyUI常用控件禁用方法
  • 原文地址:https://www.cnblogs.com/talentzemin/p/9894645.html
Copyright © 2011-2022 走看看