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

2020-10-28 11:39:44 浏览数 (1)

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

概述

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

模式结构

示意性代码

代码语言:javascript复制
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。
  • 在需要的情况下,可以较容易地将命令记入日志。
  • 命令模式把请求一个 操作的对象与知道怎么执行一个操作的对象分割开。
  • 命令类与其他任何别的类-样,可以修改和推广。

本质

封装请求。

实例:

麦当劳点单:

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

厨师 命令接收者

代码语言:javascript复制
package Command_McDonald;

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

命令抽象接口

代码语言:javascript复制
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(); 
	
}

炸鸡命令,具体命令

代码语言:javascript复制
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
	}

	 

}
代码语言:javascript复制
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
	}

	 

}
代码语言:javascript复制
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
	}
}

收银员,命令调用者

代码语言:javascript复制
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();//每样告诉后厨进行制作
		}
	}
}

0 人点赞