策略模式
# 分类
行为型模式
# 定义
- 策略模式(Strategy Pattern) 封装算法,它认为算法已经是一个完整地、不可拆分的原子业务(注意这里是原子业务不是原子对象),这些算法可以在运行时更改。
# 意图
定义一系列算法
,把它们一个个封装
起来,并且使它们可以相互替换
。
# 应用场景
- 有多个对象可以处理同一个请求,具体哪个对象处理该请求由运行时刻自动确定。
- 在不明确指定接收者的情况下,向多个对象中的一个提交一个请求。
- 可动态指定一组对象处理请求。
应用案例
- 商场搞活动
- 诸葛亮的经纳囊妙计,每一个锦囊是一个策略。
- 旅行的出游方式,选择骑自行车、坐汽车,每一种旅行方式都是一个策略。
# 角色与结构图
- Strategy:
抽象策略类角色
定义所有支持的算法的公共接口。 - ConcreteStrategy:
具体策略类角色
封装了具体的算法或行为,继承自Strategy。 - Context:
上下文类
用一个ConcreteStrategy来配置,维护一个对Strategy对象的引用。 - Client:
客户程序角色
使用策略实现功能。
下图解释了策略模式中各角色的作用

# 示例代码
// 抽象策略类
abstract class Strategy {
public abstract void AlgorithmInterface();
}
// 具体策略A
class ConcreteStrategyA : Strategy {
public override void AlgorithmInterface(){
Console.WriteLine("算法A功能");
}
}
// 具体策略B
class ConcreteStrategyB : Strategy {
public override void AlgorithmInterface(){
Console.WriteLine("算法B功能");
}
}
// 具体策略C
class ConcreteStrategyC : Strategy {
public override void AlgorithmInterface(){
Console.WriteLine("算法C功能");
}
}
//上下文
class Context{
Strategy strategy;
public Context(Strategy strategy){
this.strategy = strategy;
}
public void ContextInterface(){
strategy.AlgorithmInterface();
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
//客户端
class Client{
static void Main(String[] args){
Context context ;
context = new Context(new ConcreteStrategyA());
context.ContextInterface();
context = new Context(new ConcreteStrategyB());
context.ContextInterface();
context = new Context(new ConcreteStrategyC());
context.ContextInterface();
Console.ReadLine();
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
# 优点
- 简化了单元测试,因为每个算法都有自己的类,可以通过自己的接口单独测试。
- 策略模式
封装了变化
。 - 算法可以自由切换。
- 避免使用多重条件判断。
- 扩展性良好。
# 缺点
- 策略类会增多。
- 所有策略类都需要对外暴露。
# 小结
算法本身只是一种策略,最重要的是这些
算法是随时都可能相互替换
的,这就是变化点。封装变化点是我们面向对象的一种很重要的思维方式。策略模式是一种定义
一系列算法
的方法,从概念上来看,所有这些算法完成的都是相同的工作
,只是实现不同,它可以以相同的方式调用所有的算法,减少了各种算法类与使用算法类之间的耦合。策略模式的Strategy类层次为Context定义了一系列的可供重用的算法和行为。继承有助于析取出这些算法的公共功能。
策略模式就是用来
封装算法
的,但在实践中,我们发现可以用它来封装几乎任何类型的规则,只要在分析过程中听到需要在不同时间应用不同的业务规则
,就可以考虑使用策略模式处理这种变化的可能性。主要解决?在有多种算法相似的情况下,使用if...else...所带来的复杂和难以维护。
何时使用?一个系统又许多许多类,而区分它们的只是它们直接的行为。
如何解决?将这些算法封装成一个一个的类,任意地替换。
关键代码?实现同一个接口。
注意:如果一个系统的策略多于4个,就需要考虑使用组合模式,解决策略类膨胀的问题。
# 一句话概括
定义一系列算法,把他们封装起来,并且使它们可以相互替换。
编辑 (opens new window)
上次更新: 2025/03/22, 13:47:44