• 『设计模式』再谈麦当劳的点单模式--命令模式(Command)


    23种设计模式+额外常用设计模式汇总 (持续更新)

    麦当劳,我三期设计模式拿你举例子了,私信联系我打钱!!!

    概述

    • 命令模式又称为行动(Action) 模式或交易(Transaction) 模式。
    • 命令模式把一个请求或者操作封装到一个对象中。命令模式允许系统使用不同的请求把客户端参数化;对请求排队或者记录请求日志,可以提供命令的撤销和恢复功能
    • 命令模式是对命令的封装。命令模式把命令的责任执行命令的责任分割开,委派给不同的对象。

    模式结构

    在这里插入图片描述

    示意性代码

    namespace 命令模式
    {
        class Receiver
        {
            public void Action()
            {
                Console.WriteLine("操作成功!");
            }
        }
        abstract class Command
        {
            protected Receiver receiver;
            public Command(Receiver receiver)
            {
                this.receiver = receiver;
            }
            abstract public void Execute();
        }
        class ConcreteCommand:Command
        {
            public ConcreteCommand(Receiver receiver) : base(receiver) { }
            public override void Execute()
            {
                receiver.Action();
            }
        }
        class Invoker
        {
            private Command command;
            public void SetCommand(Command command)
            {
                this.command = command;
            }public void ExecuteCommand()
            {
                command.Execute();
            }    
        }
        class Program
        {
            static void Main(string[] args)
            {
                Receiver r = new Receiver();
                Command c = new ConcreteCommand(r);
                Invoker i = new Invoker();
                i.SetCommand(c);
                i.ExecuteCommand();
                Console.Read();
            }
        }
    }
    
    • 将请求的接收者(Receiver)放到Command的具体子类ConcreteCommand中,当请求到来时(Invoker发出Invoker消息激活Command对象),ConcreteCommand将处理请求交给Receiver对象进行处理
    • Command模式将调用操作的对象和知道如何实现该操作的对象解耦。在上面Command的结构图中,Invoker对象根本就不知道具体的是哪个对象在处理Excute操作。
    • 在Command下要增加新的处理操作对象很容易,我们可以通过创建新的继承自Command的子类来实现这一点。
    • Command模式可以和Memento模式结合起来,支持Undo的操作。

    使用命令模式情况

    • 如果需要在不同的时刻指定、排列和执行请求,可以选用命令模式,把这些请求封装成为命令对象,然后实现把请求队列化
    • 如果需要支持取消操作从可以选用命令模式,通过管理命令对象,,能很容易的实现命令的恢复和重做的功能
    • 如果需要支持当系统崩溃时,能把对系统的操作功能重新执行一遍,可以选用命令模式,把这些操作功能的请求封装成命令对象,然后实现日志命令,就可以在系统恢复回来后,通过日志获取命令列表,从而重新执行一遍功能
    • 在需要事务的系统中,可以选用命令模式,命令模式提供了对事务进行建模的方法,命令模式有二个别名就是Transaction.

    优点

    命令允许请求的一方和接收请求的一方能够独立演化。

    • 命令模式使新的命令很容易地被加入到系统里
    • 允许接收请求的一方决定是否要否决(Veto) 请求。
    • 能较容易地设计一个命令队列。
    • 可以容易地实现对请求的Undo和Redo。
    • 在需要的情况下,可以较容易地将命令记入日志。
    • 命令模式把请求一个 操作的对象与知道怎么执行一个操作的对象分割开。
    • 命令类与其他任何别的类-样,可以修改和推广。

    本质

    封装请求。

    实例:

    麦当劳点单:

    炸鸡汉堡很香,但请好好吃饭!

    在这里插入图片描述
    厨师 命令接收者

    package Command_McDonald;
    
    public class Cook {
    	public void Chicken()
    	{
    		System.out.println("做一份炸鸡");
    	}
    	public void Hamburger()
    	{
    		System.out.println("做一份汉堡包");
    	}
    	public void fries() {
    		System.out.println("做一份薯条");
    	}
    }
    
    

    命令抽象接口

    package Command_McDonald;
    
    public abstract class Command {
    	protected Cook cook_receiver;
    
    	public Command(Cook cook_receiver) {
    	 
    		this.cook_receiver = cook_receiver;
    	}
    	abstract public void  Excute_Command(); 
    	
    }
    
    

    炸鸡命令,具体命令

    package Command_McDonald;
    
    public class Chicken_Command extends Command {
    	@Override
    	public void Excute_Command() {
    		cook_receiver.Chicken();
    
    	}
    
    	public Chicken_Command(Cook cook_receiver) {
    		super(cook_receiver);
    		// TODO Auto-generated constructor stub
    	}
    
    	 
    
    }
    
    
    package Command_McDonald;
    
    public class Fries_Command extends Command {
    	@Override
    	public void Excute_Command() {
    		cook_receiver.fries();
    
    	}
    
    	public Fries_Command(Cook cook_receiver) {
    		super(cook_receiver);
    		// TODO Auto-generated constructor stub
    	}
    
    	 
    
    }
    
    
    package Command_McDonald;
    
    public class Hamburger_Command extends Command {
    	@Override
    	public void Excute_Command() {
    		cook_receiver.Hamburger();
    
    	}
    
    	public Hamburger_Command(Cook cook_receiver) {
    		super(cook_receiver);
    		// TODO Auto-generated constructor stub
    	}
    }
    
    

    收银员,命令调用者

    package Command_McDonald;
    
    import java.util.ArrayList;
    import java.util.List;
    
    public class Cashier {
    	private List<Command> Command_Undo = new ArrayList<Command>();
    
    	public void add_Command(Command com) {
    		Command_Undo.add(com); //增加命令
    	}
    
    	public void Undo_Command(Command com) {
    		Command_Undo.remove(com); //移除命令
    	}
    
    	public void Notify() // 提交菜单
    	{
    		for(Command con:Command_Undo)
    		{
    			con.Excute_Command();//每样告诉后厨进行制作
    		}
    	}
    }
    
    
  • 相关阅读:
    JSP
    Tomcat根据JSP生成Servlet机制解析
    JSON基础
    ATouch 吃鸡开发板原理及功能介绍
    Android触摸touchevent的AB两种方式(TYPE_A,TYPE_B)识别方法
    ubuntu诸软件安装
    linux kernel mini2440 start.S head-common.S 部分注释
    Android USB ADB ATUH 验证包验证流程
    USB协议学习
    Android memory dump
  • 原文地址:https://www.cnblogs.com/lunatic-talent/p/13499481.html
Copyright © 2020-2023  润新知