行为型 简单
策略模式
Strategy Pattern
定义一系列的算法,把它们一个个封装起来,并且使它们可相互替换。策略模式让算法的变化独立于使用算法的客户。
概述
策略模式是一种行为设计模式,它能让你定义一系列算法,并将每种算法分别放入独立的类中,以使算法的对象能够相互替换。
适用场景
- •当你想使用对象中各种不同的算法变体,并希望能在运行时切换算法时
- •当你有许多仅在执行某些行为时略有不同的相似类时
- •当算法在上下文的逻辑中不是特别重要时
- •当类中使用了大量的条件语句来选择不同行为时
优点
- +可以在运行时切换对象内的算法
- +可以将算法的实现和使用算法的代码隔离开来
- +可以使用组合来代替继承
- +开闭原则:无需对上下文进行修改就能够引入新的策略
- +避免使用多重条件判断语句(if-else 或 switch-case)
缺点
- −如果你的算法极少发生改变,那么没有任何理由引入新的类和接口
- −客户端必须知晓策略间的不同,以便选择合适的策略
- −增加了代码的复杂度,需要创建更多的类
- −策略类之间可能存在重复代码
结构
classDiagram
class Context {
-Strategy strategy
+setStrategy(Strategy s)
+executeStrategy()
}
class Strategy {
<<interface>>
+execute()
}
class ConcreteStrategyA {
+execute()
}
class ConcreteStrategyB {
+execute()
}
class ConcreteStrategyC {
+execute()
}
class Client {
+main()
}
Context --> Strategy : uses
Strategy <|.. ConcreteStrategyA : implements
Strategy <|.. ConcreteStrategyB : implements
Strategy <|.. ConcreteStrategyC : implements
Client ..> Context : uses
Client ..> ConcreteStrategyA : creates
Client ..> ConcreteStrategyB : creates
Client ..> ConcreteStrategyC : creates
style Context fill:#e3f2fd,stroke:#1976d2,stroke-width:2px
style Strategy fill:#fff3e0,stroke:#f57c00,stroke-width:2px
style ConcreteStrategyA fill:#e8f5e9,stroke:#388e3c,stroke-width:1px
style ConcreteStrategyB fill:#e8f5e9,stroke:#388e3c,stroke-width:1px
style ConcreteStrategyC fill:#e8f5e9,stroke:#388e3c,stroke-width:1px
style Client fill:#f5f5f5,stroke:#616161,stroke-width:1px
交互演示
运行时切换不同算法策略
选择策略
execute()
Context等待选择...
生活类比
策略模式就像是出行方式的选择
出行方式
去机场可以选择公交、地铁、出租车或自驾,这些是不同的策略,可以根据时间、预算等因素选择。
支付方式
购物时可以选择现金、信用卡、支付宝或微信支付,每种支付方式都是一种策略,根据场景灵活切换。
导航路线
导航软件提供最快路线、最短路线、避开高速等不同策略,用户可以根据需求选择。
代码实现
Example.java
实际应用
Java Collections - Comparator
Java 集合框架中的 Comparator 接口是策略模式的典型应用,允许在运行时指定不同的排序策略。
Example.java
JavaScript Array.sort()
JavaScript 数组的 sort 方法接受一个比较函数作为策略参数。
Example.java
Spring Security - AuthenticationStrategy
Spring Security 使用策略模式处理不同的认证方式(表单、OAuth、JWT 等)。
Example.java
练习
1
策略模式的主要目的是什么?
2
策略模式允许在运行时切换算法
3
以下哪个不是策略模式的优点?
4