跳转到内容
主菜单
主菜单
移至侧栏
隐藏
导航
首页
最近更改
随机页面
MediaWiki帮助
代码酷
搜索
搜索
中文(中国大陆)
外观
创建账号
登录
个人工具
创建账号
登录
未登录编辑者的页面
了解详情
贡献
讨论
编辑“︁
策略模式
”︁
页面
讨论
大陆简体
阅读
编辑
编辑源代码
查看历史
工具
工具
移至侧栏
隐藏
操作
阅读
编辑
编辑源代码
查看历史
常规
链入页面
相关更改
特殊页面
页面信息
外观
移至侧栏
隐藏
您的更改会在有权核准的用户核准后向读者展示。
警告:
您没有登录。如果您进行任何编辑,您的IP地址会公开展示。如果您
登录
或
创建账号
,您的编辑会以您的用户名署名,此外还有其他益处。
反垃圾检查。
不要
加入这个!
{{Note|本条目讲解面向对象编程中的'''策略模式'''(Strategy Pattern),适用于设计模式初学者及需要巩固概念的开发者。}} == 概述 == '''策略模式'''是一种行为型设计模式,允许在运行时选择算法的具体实现。其核心思想是将算法族(一组相关算法)封装为独立的类,使它们可以相互替换,且算法的变化不影响使用算法的客户端。 {{Definition|策略模式}} 定义一个算法族,将每个算法封装起来,并使它们可以互相替换。策略模式让算法的变化独立于使用算法的客户。 === 设计原则 === 策略模式体现了以下设计原则: * '''开闭原则''':无需修改客户端代码即可扩展新算法 * '''单一职责原则''':每个算法类只负责一个具体策略 * '''组合优于继承''':通过对象组合而非继承来实现行为变化 == 结构 == <mermaid> classDiagram class Context { -strategy: Strategy +setStrategy(Strategy) +executeStrategy() } class Strategy { <<interface>> +execute() } class ConcreteStrategyA { +execute() } class ConcreteStrategyB { +execute() } Context o--> Strategy Strategy <|-- ConcreteStrategyA Strategy <|-- ConcreteStrategyB </mermaid> 关键角色说明: * '''Context''':持有策略引用的环境类 * '''Strategy''':策略接口(抽象策略) * '''ConcreteStrategy''':具体策略实现 == 代码示例 == 以下示例展示排序策略的可互换实现: === Java 实现 === <syntaxhighlight lang="java"> // 策略接口 interface SortStrategy { void sort(int[] data); } // 具体策略A:冒泡排序 class BubbleSort implements SortStrategy { @Override public void sort(int[] data) { System.out.println("使用冒泡排序"); // 实际排序实现... } } // 具体策略B:快速排序 class QuickSort implements SortStrategy { @Override public void sort(int[] data) { System.out.println("使用快速排序"); // 实际排序实现... } } // 上下文类 class Sorter { private SortStrategy strategy; public void setStrategy(SortStrategy strategy) { this.strategy = strategy; } public void executeSort(int[] data) { strategy.sort(data); } } // 客户端代码 public class Main { public static void main(String[] args) { Sorter sorter = new Sorter(); int[] data = {5, 2, 9, 1, 5}; sorter.setStrategy(new BubbleSort()); sorter.executeSort(data.clone()); sorter.setStrategy(new QuickSort()); sorter.executeSort(data.clone()); } } </syntaxhighlight> {{Output| 使用冒泡排序 使用快速排序 }} === Python 实现 === <syntaxhighlight lang="python"> from abc import ABC, abstractmethod # 策略接口 class SortStrategy(ABC): @abstractmethod def sort(self, data): pass # 具体策略 class BubbleSort(SortStrategy): def sort(self, data): print("使用冒泡排序") # 实际排序实现... class QuickSort(SortStrategy): def sort(self, data): print("使用快速排序") # 实际排序实现... # 上下文 class Sorter: def __init__(self, strategy: SortStrategy): self._strategy = strategy def sort(self, data): self._strategy.sort(data) # 客户端 if __name__ == "__main__": data = [5, 2, 9, 1, 5] sorter = Sorter(BubbleSort()) sorter.sort(data.copy()) sorter = Sorter(QuickSort()) sorter.sort(data.copy()) </syntaxhighlight> == 应用场景 == 策略模式适用于以下情况: * 需要动态切换算法时 * 有多个条件语句选择不同算法变体时 * 算法需要独立于使用它的客户端时 === 真实案例 === '''电商系统折扣策略''': <mermaid> classDiagram class CheckoutService { -discountStrategy: DiscountStrategy +applyDiscount(order) } class DiscountStrategy { <<interface>> +calculateDiscount(order) } class ChristmasDiscount { +calculateDiscount(order) } class BlackFridayDiscount { +calculateDiscount(order) } CheckoutService o--> DiscountStrategy DiscountStrategy <|-- ChristmasDiscount DiscountStrategy <|-- BlackFridayDiscount </mermaid> == 优缺点 == {{Pros| * 避免使用多重条件语句 * 符合开闭原则 * 提高代码的可测试性 * 算法可以自由切换 }} {{Cons| * 客户端必须了解所有策略差异 * 会增加对象数量 * 策略类需要对外暴露 }} == 相关模式 == * '''状态模式''':策略模式类似,但策略模式中的策略是静态配置的,而状态模式中的状态会随着上下文自动变化 * '''工厂模式''':常与策略模式结合使用来创建具体策略对象 * '''命令模式''':将操作封装为对象,策略模式则是封装算法 == 数学表达 == 策略模式可以形式化表示为: <math> \begin{cases} Context \rightarrow Strategy \\ \forall s \in ConcreteStrategies,\ s \subseteq Strategy \\ execute() = \begin{cases} s_1.execute() & \text{if strategy}=s_1 \\ s_2.execute() & \text{if strategy}=s_2 \\ ... \\ s_n.execute() & \text{if strategy}=s_n \end{cases} \end{cases} </math> 其中: * <math>Context</math> 依赖于抽象策略 <math>Strategy</math> * 具体策略 <math>s_1, s_2,...,s_n</math> 实现策略接口 == 进阶思考 == * 如何结合依赖注入框架管理策略? * 策略模式与Lambda表达式的关系? * 如何避免策略膨胀问题? [[Category:计算机科学]] [[Category:面试技巧]] [[Category:设计模式]]
摘要:
请注意,所有对代码酷的贡献均被视为依照知识共享署名-非商业性使用-相同方式共享发表(详情请见
代码酷:著作权
)。如果您不希望您的文字作品被随意编辑和分发传播,请不要在此提交。
您同时也向我们承诺,您提交的内容为您自己所创作,或是复制自公共领域或类似自由来源。
未经许可,请勿提交受著作权保护的作品!
取消
编辑帮助
(在新窗口中打开)
该页面使用的模板:
模板:Cons
(
编辑
)
模板:Definition
(
编辑
)
模板:Note
(
编辑
)
模板:Output
(
编辑
)
模板:Pros
(
编辑
)