程序中可能会遇到某处代码,需要一系列判断,来决定执行哪个方法,判断和执行的逻辑又有可能随着业务逻辑改变,从而变得难以维护。命令模式来了,它不仅可以封装调用,甚至还能实现“撤销”。
什么是命令模式?
将“请求”封装成对象,以便使用不同的请求、队列或者日志来参数化其他对象。这种模式还支持可撤销的操作。
例子:
调用者与执行者
在例子中,调用者依赖执行者对象,两者耦合在一起了。而且弹性小,当业务改变时,就得修改调用者代码;而且如果 executer 类型变了,甚至可能原来的 methodA 等方法都没有了,还是要改调用者代码。

然后,执行者方法中依赖 Command 对象,原来方法调用的部分,用 Commond 的 execute() 替换。

这样一来,调用者就和执行者解耦了,调用者不用关心执行者有哪些方法,怎么执行,他只要调用 command.execute() 。
另外,在上图例子中 ① 标注的位置,使用的 是 Command 对象,根据出入不同的 Command 实现类对象,就可以定义不同的操作。其实这里很灵活的,可以换成数组、集合、队列甚至是记录文件,这样可以报需要执行的命令都保存下来,什么时候执行,按照什么顺序执行都是可控的。我们还可以再加一个属性(对象、数组、集合、队列、记录文件等),用来存储撤销命令的,在必要时候,调用 undo() 即可完成撤销。这样一来,调用者就有了较高的弹性。
典型应用
日志系统:将命令记录在日志中,一旦系统崩了,可以根据日志文件记录的命令进行恢复。
事务管理:一旦事务中未能完整完成,即可根据记录的命令进行撤销。
网友评论