设计模式——命令模式
命令模式:将命令封装成对象(下面示例中的Command对象),实现命令请求和命令执行者的解耦!
应用场景:1、出现一组命令的时候。2、需要实现undo操作的时候。3、命令请求与执行可能不是同步的是,需要实现异步处理;4、命令需要事务控制的时候
角色:
receiver执行命令的具体对象,命令的实际执行者!
ICommand 命令的抽象接口,将一组命令进行抽象;一般包含一个执行方法,一个undo方法;
Command 继承于ICommand,并实现命令的调用;
Invoker 命令调度者,
下面看具体实现:
/* * Copyright (c) 2017. Xiaomi.Co.Ltd All rights reserved */ package com.pt.command; /** * @description 命令对象的抽象类 * @author panteng * @date 17-2-21. */ public interface ICommand { void excute(); void undo(); }
/* * Copyright (c) 2017. Xiaomi.Co.Ltd All rights reserved */ package com.pt.command; /** * @description Receiver命令的具体执行者 * 厨房,可以做各种食物 * @author panteng * @date 17-2-21. */ public class KitchenReceiver { public void getPie(){ System.out.println("做一张大饼... ..."); } public void getNoodles(){ System.out.println("做一碗面条... ..."); } public void getDumplings(){ System.out.println("做一碗面条... ..."); } }
/* * Copyright (c) 2017. Xiaomi.Co.Ltd All rights reserved */ package com.pt.command; /** * @description 命令对象 * @author panteng * @date 17-2-21. */ public class NoodlesCommand implements ICommand { KitchenReceiver receiver; public NoodlesCommand(){ } public NoodlesCommand(KitchenReceiver r){ this.receiver = r; } public void excute(){ receiver.getNoodles(); } public void undo(){ System.out.println("取消面条订单... ..."); } public KitchenReceiver getReceiver(){ return receiver; } public void setReceiver(KitchenReceiver receiver){ this.receiver = receiver; } }
/* * Copyright (c) 2017. Xiaomi.Co.Ltd All rights reserved */ package com.pt.command; /** * @description 命令对象 * @author panteng * @date 17-2-21. */ public class PieCommand implements ICommand { KitchenReceiver receiver; public PieCommand(){ } public PieCommand(KitchenReceiver receiver){ this.receiver = receiver; } public void excute(){ receiver.getPie(); } public void undo(){ System.out.println("取消大饼订单... ..."); } public KitchenReceiver getReceiver(){ return receiver; } public void setReceiver(KitchenReceiver receiver){ this.receiver = receiver; } }
/* * Copyright (c) 2017. Xiaomi.Co.Ltd All rights reserved */ package com.pt.command; /** * @description 命令对象 * @author panteng * @date 17-2-21. */ public class DumplingsCommand implements ICommand { KitchenReceiver receiver; public DumplingsCommand(){ } public DumplingsCommand(KitchenReceiver r){ this.receiver = r; } public void excute(){ receiver.getDumplings(); } public void undo(){ System.out.println("取消水饺订单... ..."); } public KitchenReceiver getReceiver(){ return receiver; } public void setReceiver(KitchenReceiver receiver){ this.receiver = receiver; } }
/* * Copyright (c) 2017. Xiaomi.Co.Ltd All rights reserved */ package com.pt.command; import java.util.ArrayList; import java.util.List; /** * @description * @author panteng * @date 17-2-21. */ public class WaiterInvoker { List<ICommand> commands = new ArrayList<ICommand>(); public void order(){ while (commands.size() > 0) { commands.get(0).excute(); synchronized (WaiterInvoker.class) { commands.remove(0); } } } public void cancelOrder(ICommand iCommand){ if (commands.contains(iCommand)) {//还未执行,直接移除 commands.remove(iCommand); } else {//已经执行 iCommand.undo(); } } public ICommand addCommand(ICommand iCommand){ synchronized (WaiterInvoker.class) { commands.add(iCommand); return iCommand; } } }
/* * Copyright (c) 2017. Xiaomi.Co.Ltd All rights reserved */ package com.pt.command; import org.junit.Test; /** * @description * @author panteng * @date 17-2-21. */ public class CommandTest { @Test public void commandTest(){ KitchenReceiver receiver = new KitchenReceiver();//厨房 ICommand getNoodles = new NoodlesCommand(receiver); ICommand getDumplings = new DumplingsCommand(receiver); ICommand getPie = new PieCommand(receiver); WaiterInvoker waiter = new WaiterInvoker(); waiter.addCommand(getNoodles); waiter.addCommand(getDumplings); waiter.order(); waiter.addCommand(getPie); waiter.order(); waiter.cancelOrder(getPie); } }