策略模式

# 分类

行为型模式

# 定义

  • 策略模式(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
//客户端
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

# 优点

  • 简化了单元测试,因为每个算法都有自己的类,可以通过自己的接口单独测试。
  • 策略模式封装了变化
  • 算法可以自由切换。
  • 避免使用多重条件判断。
  • 扩展性良好。

# 缺点

  • 策略类会增多。
  • 所有策略类都需要对外暴露。

# 小结

  • 算法本身只是一种策略,最重要的是这些算法是随时都可能相互替换的,这就是变化点。封装变化点是我们面向对象的一种很重要的思维方式。

  • 策略模式是一种定义一系列算法的方法,从概念上来看,所有这些算法完成的都是相同的工作,只是实现不同,它可以以相同的方式调用所有的算法,减少了各种算法类与使用算法类之间的耦合。

  • 策略模式的Strategy类层次为Context定义了一系列的可供重用的算法和行为。继承有助于析取出这些算法的公共功能。

  • 策略模式就是用来封装算法的,但在实践中,我们发现可以用它来封装几乎任何类型的规则,只要在分析过程中听到需要在不同时间应用不同的业务规则,就可以考虑使用策略模式处理这种变化的可能性。

  • 主要解决?在有多种算法相似的情况下,使用if...else...所带来的复杂和难以维护。

  • 何时使用?一个系统又许多许多类,而区分它们的只是它们直接的行为。

  • 如何解决?将这些算法封装成一个一个的类,任意地替换。

  • 关键代码?实现同一个接口。

  • 注意:如果一个系统的策略多于4个,就需要考虑使用组合模式,解决策略类膨胀的问题。

# 一句话概括

定义一系列算法,把他们封装起来,并且使它们可以相互替换。

上次更新: 2025/03/22, 13:47:44
最近更新
01
Git问题集合
01-29
02
安装 Nginx 服务器
01-25
03
安装 Docker 容器
01-25
更多文章>
×
×