A: 调用方
B:被调用方
假设: A 需要依次调用B的多个方法
方式一:
A直接new B()
A依次调用B的多个方法
优缺点:
实现简单。紧耦合,而且A需要关心整个调用顺序。将来如果流程逻辑修改了,A需要修改调用流程。
方式二:
A直接new B()
A调用B的某个方法
B的方法依次调用B的多个方法
优缺点:
实现简单。A与B耦合一个方法,正常的业务流程中经常写这种代码,没有对流程做抽象,不够高级。
方式三:
A直接new B()
A直接new Command() 【命令】
A直接new Invoker() 【请求者】
A关联Command和B Command和Invoker;
A调用Invoker
Invoker调用Command
Command依次调用B的多个方法
优缺点:
整个流程变复杂了。Invoker只会直接调用Command的默认方法,没有其余的逻辑,这里做这层抽象主要精力还是花费在调用上; 用线程池来执行?是否需要保证多个command之间的调用顺序?等等吧;个人觉得如果不需要。精华在于Command,所有的业务逻辑都压在了Command身上,但是Command又依据场景而生,每个场景都会有一个Command,所以彼此都是独立存在的;缺点是场景越多,Command就越多,其次Command的返回值需要规范好。B无需关心怎么组合了,所有的组织流程都抽象到了Command里面。
越写越感觉命令模式很类似于 ThreadPoolExecutor 提交 Callable 任务。
ThreadPoolExecutor == Invoker
Callable == Command
Receiver == Command其中调用的各式逻辑
命令模式应用场景
场景就是一个命令的时候【摘抄】 -- 这个非常模糊了,什么请求不是个命令呢,增删改查是命令;特殊的 ls / rm /df 之类的也是命令。命令就是要求去做一件事情,那么到底什么时候可以抽象成命令模式呢? 什么时候需要用命令模式呢?
在我理解命令模式中的Command无非就是把对Receiver的调用逻辑做了封装,Receiver只需要提供原子操作即可。那就是调用方无需关系业务流程细节,只要知道自己现在是什么命令,由谁执行即可。
命令模式本身并没有什么特别的,最重要的是场景与Command一一对应,这个可以让项目变得更加清晰,所见即所得。应用场景想来也不多,不过有个感触就是,其实需求用什么方式都能实现,问题在于如何才能实现的优雅。