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

命令模式

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

结构图


代码实现

抽象命令类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;
	}

	@Override
	public 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);
	}

	@Override
	public void excutedCommand() {
		barbecuer.bakeMutton();
	}

}

/**
 * 烤鸡翅命令
 *
 * @author xukai 2016年3月30日 下午11:58:04
 * 
 */
public class BakeChickenWingCommand extends Command {

	public BakeChickenWingCommand(Barbecuer barbecuer) {
		super(barbecuer);
	}

	@Override
	public 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
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
1) 优秀的程序应该是这样的:阅读时,感觉很优雅;新增功能时,感觉很轻松;运行时,感觉很快速,这就需要设计模式支撑。2) 设计模式包含了大量的编程思想,讲授和真正掌握并不容易,网上的设计模式课程不少,大多讲解的比较晦涩,没有真实的应用场景和框架源码支撑,学习后,只知其形,不知其神。就会造成这样结果: 知道各种设计模式,但是不知道怎么使用到真实项目。本课程针对上述问题,有针对性的进行了升级 (1) 授课方式采用 图解+框架源码分析的方式,让课程生动有趣好理解 (2) 系统全面的讲解了设计模式,包括 设计模式七大原则、UML类图-类的六大关系、23种设计模式及其分类,比如 单例模式的8种实现方式、工厂模式的3种实现方式、适配器模式的3种实现、代理模式的3种方式、深拷贝等3) 如果你想写出规范、漂亮的程序,就花时间来学习设计模式吧课程内容和目标本课程是使用Java来讲解设计模式,考虑到设计模式比较抽象,授课采用 图解+框架源码分析的方式1) 内容包括: 设计模式七大原则(单一职责、接口隔离、依赖倒转、里氏替换、开闭原则、迪米特法则、合成复用)、UML类图(类的依赖、泛化和实现、类的关联、聚合和组合) 23种设计模式包括:创建型模式:单例模式(8种实现)、抽象工厂模式、原型模式、建造者模式、工厂模式。结构型模式:适配器模式(3种实现)、桥接模式、装饰模式、组合模式、外观模式、享元模式、代理模式(3种实现)。行为型模式:模版方法模式命令模式、访问者模式、迭代器模式、观察者模式、中介者模式、备忘录模式、解释器模式(Interpreter模式)、状态模式、策略模式、职责链模式(责任链模式)2) 学习目标:通过学习,学员能掌握主流设计模式,规范编程风格,提高优化程序结构和效率的能力。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值