『设计模式』再谈麦当劳的点单模式--命令模式(Command)
麦当劳,我三期设计模式拿你举例子了,私信联系我打钱!!!
概述
- 命令模式又称为行动(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();//每样告诉后厨进行制作
}
}
}