设计模式学习笔记——命令模式

来源:互联网 发布:手机优酷网络连接失败 编辑:程序博客网 时间:2024/05/17 18:47

命令模式

命令模式,将一个请求封装成一个对象,从而让你使用不同的请求把客户端参数化,对请求排队或者记录请求日志,可以提供命令的撤销和恢复功能。(行为类模式)

结构图


代码实现

抽象命令类Command
/** * 声明命令,对外公布 * * @author xukai 2016年3月30日 下午11:27:18 *  */public abstract class Command {public abstract void execute();}

调用者Invoker
/** * 调用者,调用命令 * * @author xukai 2016年3月30日 下午11:28:04 *  */public class Invoker {private Command command;public void setCommand(Command command) {this.command = command;}public void action() {command.execute();}}

接受者Receiver
/** * 接受者,负责接受命令和执行命令 * * @author xukai 2016年3月30日 下午11:29:07 *  */public class Receiver {public void doSomething() {System.out.println("接受者-业务逻辑处理");}}

命令类:ConcreteCommand
/** * 具体命令的实现 * * @author xukai 2016年3月30日 下午11:33:40 *  */public class ConcreteCommand extends Command {private Receiver receiver;public ConcreteCommand(Receiver receiver) {super();this.receiver = receiver;}@Overridepublic void execute() {receiver.doSomething();}}

客户端调用:
public class Client {public static void main(String[] args) {Receiver receiver = new Receiver();Command command = new ConcreteCommand(receiver);// 直接执行命令command.execute();// 通过调用者执行命令Invoker invoker = new Invoker();invoker.setCommand(command);invoker.action();}}
输出:
接受者-业务逻辑处理接受者-业务逻辑处理

demo

问题:烧烤店点菜。

结构图


代码实现

抽象命令Command
/** * 抽象命令 * * @author xukai 2016年3月30日 下午11:53:19 *  */public abstract class Command {protected Barbecuer barbecuer;public Command(Barbecuer barbecuer) {super();this.barbecuer = barbecuer;}public abstract void excutedCommand();}

具体命令
/** * 烤羊肉串命令 * * @author xukai 2016年3月30日 下午11:57:01 *  */public class BakeMuttonCommand extends Command {public BakeMuttonCommand(Barbecuer barbecuer) {super(barbecuer);}@Overridepublic void excutedCommand() {barbecuer.bakeMutton();}}

/** * 烤鸡翅命令 * * @author xukai 2016年3月30日 下午11:58:04 *  */public class BakeChickenWingCommand extends Command {public BakeChickenWingCommand(Barbecuer barbecuer) {super(barbecuer);}@Overridepublic void excutedCommand() {barbecuer.bakeChickenWing();}}

烤肉者:
/** * 做烧烤的人:请求的的处理者 * * @author xukai 2016年3月30日 下午11:54:38 *  */public class Barbecuer {public void bakeMutton() {System.out.println("烤羊肉串");}public void bakeChickenWing() {System.out.println("烤鸡翅");}}

服务员:
/** * 服务员:请求接受者 * * @author xukai 2016年3月30日 下午11:58:36 *  */public class Waiter {private List<Command> orders = new ArrayList<>();public void setOrder(Command command) {orders.add(command);System.out.println("增加订单:" + command.toString() + ",时间: " + (new Date()));}public void cancle(Command command) {orders.remove(command);System.out.println("取消订单:" + command.toString() + ",时间 :" + (new Date()));}public void resolve() {for (Command command : orders) {command.excutedCommand();}}}
客户端:
public class Client {public static void main(String[] args) {// 开店准备// 烧烤师Barbecuer barbecuer = new Barbecuer();// 提供命令Command bakeMuttonCommand1 = new BakeMuttonCommand(barbecuer);Command bakeMuttonCommand2 = new BakeMuttonCommand(barbecuer);Command bakeChickenWingCommand1 = new BakeChickenWingCommand(barbecuer);Waiter waiter = new Waiter();// 服务员添加菜单waiter.setOrder(bakeMuttonCommand1);waiter.setOrder(bakeMuttonCommand2);waiter.setOrder(bakeChickenWingCommand1);// 菜单交给烧烤师waiter.resolve();// 客人该主意了,不要鸡翅了waiter.cancle(bakeChickenWingCommand1);// 菜单交给烧烤师waiter.resolve();}}
客户端输出:
增加订单:com.xk.day0330.command.demo.BakeMuttonCommand@41a7d9e7,时间: Thu Mar 31 00:14:16 CST 2016增加订单:com.xk.day0330.command.demo.BakeMuttonCommand@360088ee,时间: Thu Mar 31 00:14:18 CST 2016增加订单:com.xk.day0330.command.demo.BakeChickenWingCommand@5d1ddcf4,时间: Thu Mar 31 00:14:18 CST 2016烤羊肉串烤羊肉串烤鸡翅取消订单:com.xk.day0330.command.demo.BakeChickenWingCommand@5d1ddcf4,时间 :Thu Mar 31 00:14:18 CST 2016烤羊肉串烤羊肉串
把吃烧烤分成了三步:客户点菜,服务员记录菜单,烧烤师做烧烤,实现了松耦合。

总结

优点(封装性好,扩展性好)

1.容易形成命令队列;
2.命令可以写入日志;
3.允许接受请求的一方决定是否要否决请求(如:烤肉卖完了);
4.可以实现撤销和重做;
5.各个具体命令类相互之间不影响;

缺点

命令假如过多,那么每一个命令都需要一个命令类封装,哪怕只是很简单的命令或者几行代码的事。

核心:把请求一个操作的对象与知道怎么执行一个操作的对象分割开。

敏捷开发原则

不要为代码添加基于猜测的、实际不需要的功能。如果不清楚一个系统是否需要命令模式,一般不要着急去实现它,事实上,在需要的时候通过重构实现并不困难,只有在真正需要撤销、恢复等功能时,重构原来代码为命令模式才有意义。
0 0
原创粉丝点击