先上类图
策略模式(左),命令模式(右)
策略模式和命令模式都是通过引入一个中间层来实现客户端和实现者的解耦,策略模式的中间层使用的是上下文Context,而命令模式则使用的是命令Command。通过解耦,使得客户端不用关心实现者的具体实现细节,实现者的改动不会影响到客户端,符合开闭原则以及方便单元测试。那么两者的区别是什么呢?
根据类图不难发现,策略模式主要针对算法抽象(Strategy策略接口),它将每个算法封装到一个单独的类中,使得客户端可以根据具体情况在这些策略之间进行切换,策略模式关注的是定义一系列可互换的算法或行为,允许在运行时选择和替换不同的策略。而命令模式则是针对请求抽象(Command命令接口),Command 通过将任何操作转换为对象,操作的参数将成为该对象的字段。从而实现使得请求可以被存储、延迟、排队、撤销、重试以及发送到远程服务器等。可以理解为策略模式侧重于不同策略类实现与切换,而命令模式则侧重于对(不同)请求的封装。
除此之外,根据类图还可以发现,命令模式除了客户端Client以外,还包含调用者Invoker, 调用者是调用Command接口execute()方法的程序,它对具体命令一无所知,它只知道命令接口。调用程序对象、命令对象和接收器对象由客户端对象保存,客户端决定将哪些接收器对象分配给命令对象,以及将哪些命令分配给调用程序。
在实际使用中,策略模式用于替代条件语句和多分支逻辑,允许客户端任意切换不同策略(比如线程池的拒绝策略)而命令模式则用于将请求封装为对象以支持多种操作模式,如命令队列、撤销/重做功能等(比如JDK中的Runnable接口)。