深入理解Java设计模式之命令模式
一、什么是命令模式
命令模式是一个高内聚的模式,其定义为:将一个请求封装成一个对象,从而让你使用不同的请求把客户端参数化,对请 求排队或者记录请求日志,可以提供命令的撤销和恢复功能。
在该类图中,我们看到三个角色:
-
receiver
接受者角色:该角色就是干活的角色,命令传递到这里是应该被执行的 -
command
命令角色:需要执行的所有命令都在这里声明 -
invoker
调用者角色:接收到命令,并执行命令
二、命令模式的使用场景
使用时机:当需要先将一个函数登记上,然后再以后调用此函数时,就需要使用命令模式,其实这就是回调函数。
有时候需要向某些对象发送请求,但是并不知道请求的接收者是谁,也不知道被请求的操作是什么。此时希望用一种松耦合的方式来设计程序,使得请求发送者和请求接收者能够消除彼此之间的耦合关系
例子:拿订餐来说,客人需要向厨师发送请求,但是完全不知道这些厨师的名字和联系方式,也不知道厨师炒菜的方式和步骤。 命令模式把客人订餐的请求封装成 command 对象,也就是订餐中的订单对象。这个对象可以在程序中被四处传递,就像订单可以从服务员手中传到厨师的手中。这样一来,客人不需要知道厨师的名字,从而解开了请求调用者和请求接收者之间的耦合关系
三、命令模式的优缺点
优点:
类间解耦:调用者角色与接收者角色之间没有任何依赖关系,调用者实现功能时只需调用command 抽象类的execute方法就可以,不需要了解到底是哪个接收者执行。可扩展性:command的子类可以非常容易地扩展,而调用者invoker和高层次的模块client不产生严 重的代码耦合。命令模式结合其他模式会更优秀:命令模式可以结合责任链模式,实现命令族解析任务;结合模板方法模式,则可以减少 command子类的膨胀问题。
缺点:
命令模式也是有缺点的,请看command的子类:如果有n个命令,问题就出来 了,command的子类就可不是几个,而是n个,这个类膨胀得非常大,这个就需要读者在项 目中慎重考虑使用。
四、命令模式的实现
receiver
类,知道如何实施与执行一个与请求相关的操作,任何类都可能作为一个接受者
class receiver { public void action() { console.writeline("执行请求!"); } }
command
类,用来声明执行操作的接口
abstract class command { protected receiver receiver; public command(receiver receiver) { this.receiver = receiver; } abstract public void execute(); }
concretecommand
类,将一个接受者对象绑定于一个动作,调用接受者相应的操作,以实现execute。
class concretecommand : command { public concretecommand(receiver receiver) : base(receiver) { } public override void execute() { receiver.action(); } }
invoker
类,要求该命令执行这个请求
class invoker { private command command; public void setcommand(command command) { this.command = command; } public void executecommand() { command.execute(); } }
客户端代码
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(); }
五、总结
命令模式的意图是将一个请求封装成一个对象,从而使您可以用不同的请求对客户进行参数化。
命令模式主要解决的问题是在软件系统中,行为请求者与行为实现者通常是一种紧耦合的关系,但某些场合,比如需要对行为进行记录、撤销或重做、事务等处理时,这种无法抵御变化的紧耦合的设计就不太合适。
在某些场合,比如要对行为进行"记录、撤销/重做、事务"等处理,这种无法抵御变化的紧耦合是不合适的。在这种情况下,如何将"行为请求者"与"行为实现者"解耦?将一组行为抽象为对象,可以实现二者之间的松耦合,这是命令模式的使用场景。
系统需要支持命令的撤销(undo)操作和恢复(redo)操作,也可以考虑使用命令模式
命令模式的实现过程通过调用者调用接受者执行命令,顺序:调用者→接受者→命令。
本篇文章就到这里了,希望能够给你带来帮助,也希望您能够多多关注的更多内容!
上一篇: 匹配模式 - XSL教程 - 4
下一篇: 新手学习Java对Redis简单操作