区别
- 意图不同
- 结构不同
- 命令模式:包含命令接口、具体命令类、接收者和调用者。具体命令类持有接收者的引用,在执行命令时调用接收者的方法。调用者负责调用命令的执行。
- 策略模式:包含策略接口、具体策略类和上下文类。上下文类持有策略接口的引用,通过构造函数或设置方法来传入具体策略对象,然后调用策略对象的方法。
- 使用方式不同
- 命令模式:通常用于需要对操作进行记录、撤销或重做等场景,例如图形编辑软件中的操作历史记录、文本编辑器中的撤销和重做功能等。每个操作都被封装成一个命令对象,方便管理和操作。
- 策略模式:用于当有多种算法可以选择,并且希望在运行时能够轻松切换算法的场景。比如不同的排序算法、不同的支付策略等。
使用场景
- 命令模式
- 操作记录与回放:在需要记录用户操作以便回放或审计的系统中,如游戏中的操作录制与回放、工作流系统中的任务执行记录等。例如,游戏中玩家的移动、攻击等操作可以封装成命令对象,保存下来,之后可以按照顺序重新执行这些命令来回放游戏过程。
- 异步任务处理:将任务封装成命令对象,放入任务队列中,由线程池异步执行。比如在一个大型的文件处理系统中,文件的压缩、解压等操作可以封装成命令对象,放入队列中,由后台线程异步处理。
- 操作撤销与重做:在文本编辑器、图形设计软件等工具中,用户的每一步操作(如删除、添加、修改等)都可以封装成命令对象,通过维护一个命令历史记录栈,实现撤销和重做功能。
- 策略模式
- 算法切换:在软件开发中,当一个功能有多种实现算法,并且需要在运行时根据不同条件选择不同算法时,使用策略模式。例如,在电商系统中,根据用户的会员等级、促销活动等不同条件,选择不同的折扣计算策略。
- 可插拔功能:希望将某些功能模块设计成可插拔的,方便在不修改核心代码的情况下替换功能实现。比如在一个安全系统中,不同的加密算法可以作为不同的策略,根据系统需求随时更换加密策略。
示例代码对比
命令模式示例代码
// 命令接口
interface Command {
fun execute()
}
// 接收者类
class Receiver {
fun action() {
println("Receiver is performing an action")
}
}
// 具体命令类
class ConcreteCommand(private val receiver: Receiver) : Command {
override fun execute() {
receiver.action()
}
}
// 调用者类
class Invoker {
private var command: Command? = null
fun setCommand(command: Command) {
this.command = command
}
fun executeCommand() {
command?.execute()
}
}
策略模式示例代码
// 策略接口
interface Strategy {
fun execute()
}
// 具体策略类A
class ConcreteStrategyA : Strategy {
override fun execute() {
println("Executing ConcreteStrategyA")
}
}
// 具体策略类B
class ConcreteStrategyB : Strategy {
override fun execute() {
println("Executing ConcreteStrategyB")
}
}
// 上下文类
class Context(private var strategy: Strategy) {
fun setStrategy(strategy: Strategy) {
this.strategy = strategy
}
fun executeStrategy() {
strategy.execute()
}
}
通过以上对比,可以清晰地看出命令模式和策略模式在设计意图、结构和使用场景上的差异。
当前文章价值6.68元,扫一扫支付后添加微信提供帮助!(如不能解决您的问题,可以申请退款)

评论已关闭!