定义:
命令模式(Command),将一个请求封装为一个对象,从而使你可用不同的请求对客户进行参数化;对请求排队或记录请求日志,以及支持可撤销的操作。
为什么需要命令模式?
在我们的软件开发系统中,行为请求者和真正的执行者通常都是一种紧耦合关系,但是这种情况下,当我们需要修改行为时,如需要撤销或者重做时,只能修改请求者的源代码,
命令模式会通过在行为请求者和执行者之间引入一个抽象接口来将请求者和执行者进行解耦,这样如果需要修改行为时,只需要增加对应行为的命令就可以了,完全不需要修改请求者的源代码。通过在你的请求者和真正的执行者之间加上了一个中间人的角色,来达到分离耦合的目的。
命令模式的目的就是达到命令的发出者和执行者之间解耦,实现请求和执行分开。
命令模式的作用:
-
第一,它能较容易地设计一个命令队列;
-
第二,在需要的请情况下,可以较容易地将命令记入日志;
-
第三,允许接收请求的一方决定是否要否决请求;
-
第四,可以容易地实现对请求的撤销和重做;
-
第五,由于加进新的具体命令类不影响其他的类,因此增加新的具体命令类很容易。还有就是,命令模式把请求一个操作对象与知道怎么执行一个操作的对象分割开。
结构图:
调用者-Invoker
实例:
优点:
-
通过引入中间件(抽象接口),解耦了命令请求与实现。降低了系统耦合度
-
扩展性良好,可以很容易地增加新命令。新的命令可以很容易添加到系统中去。
-
支持组合命令,支持命令队列。
-
可以在现有命令的基础上,增加额外功能,比如日志记录,结合装饰器模式会更加灵活
缺点:
-
具体命令类可能过多。
-
命令模式的结果其实就是接收方的执行结果,但是为了以命令的形式进行架构、解耦请求与实现,引入额外类型结构(引入请求方与抽象命令接口)。
-
增加了理解上的困难。不过这也是设计模式的通病抽象必然会额外增加类的数量;代码抽离肯定比代码聚合更难理解。
适用场景:
-
现实语义中存在具备“命令”的操作,如:dos命令,shell命令
-
数据库中的事务机制的底层实现
-
需要支持命令宏(即命令组合)操作。
-
命令的撤销和恢复:增加相应的撤销和恢复命令的方法(比如数据库中的事务回滚)