解决问题:
“行为请求者”与“行为实现者”的紧耦合。尤其在对请求排队、记录请求日志、支持可撤销的操作等行为时,缺点更加明显,导致容易出错、混乱。
请求者多时,操作者无法把请求者与操作请求一一对应起来;
请求者修改请求操作时,操作者无法把请求者与修改的操作请求一一对应起来;
很容易导致请求者的请求顺序混乱,不宜修改、扩展。
定义:
将一个请求封装为一个对象,从而使你可用不同的请求对客户进行参数化;对请求排队或记录请求日志,以及支持可撤销的操作。
优点:
1.能比较容易地设计一个命令队列;
2.在需要的情况下,可以较容易地将命令记入日志;
3.允许接收请求的一方决定时候要否决请求;
4.容易地实现对请求的撤销和重做;
5.由于加进新的具体命令类,不影响其他的类,因此增加新的命令类很容易
6.最关键,命令模式把请求一个操作的对象与知道怎么执行一个操作的对象分割开。
结构图:
Command类
ConcreteCommand类
Invoker类
Receiver类
客户端:
示例:
松耦合设计
Command:命令抽象类
具体命令类:
Waiter:服务员类
Barbecuer:烤肉串类
客户端:
问题:
1.真实情况其实并不是用户点一个菜,服务员就通知厨房去做一个,应该是点完烧烤后,服务员一次通知制作。
2.如果鸡翅没了,不应该是客户来判断是否还有,而应该是服务员或者烤肉串者来否决这个请求。
3.客户到底点了哪些超考、饮料需要记录日志,已备收费,包括日后的统计。
4.客户完全可能考虑取消一些还没有制作的肉串。
优化:
客户端:
对比:紧耦合设计
Barbecuer
客户端:
缺点:
请求者多了,容易乱,分不清哪个请求对应哪个请求者,导致没有顺序、混乱;
无法区分哪个撤销操作对应哪个请求者;
结账时,因为请求与请求者不对应,容易出错,应该有日志记录;
总之,行为请求者与行为实现者的紧耦合,容易出错、混乱。
注意:
是否碰到类似的情况就一定要实现命令模式?
不一定,例如,不清楚是否需要撤销、恢复操作功能,就不要用命令模式实现。
敏捷开发原则告诉我们,不要为代码添加基于猜测的、实际不需要的功能。如果不清楚一个系统是否需要命令模式,一般不要着急去实现它,事实上,在需要的时候通过重构实现这个模式并不困难,只有在真正需要如撤销、恢复操作等功能时,把原来的代码重构为命令模式才有意义。
扩展:
编程注入生活。
重点:
命令作为对象,可扩展
下命令的人(服务员),无需知道命令(做菜)怎样操作,只需要知道下命令的对象(凉菜师傅、面点师傅、炒菜师傅),并传递命令执行需要知道的信息(订单信息|)
其他博客: