Strategy pattern(策略模式)

106 阅读2分钟

背景

image.png

现在父类加入一个 fly(),子类中加入一个橡皮鸭不会嘎嘎叫,因此 quack() 被重写为“Squeak”(吱吱叫声)

image.png

问题

  1. 固定行为: 所有的鸭子子类都继承了默认的 quackfly 行为,这意味着这些行为是固定的。如果某个具体的鸭子子类需要不同的行为,就需要修改现有的继承链或者引入新的子类,导致类的爆炸问题。
  2. 耦合性高: 所有的鸭子子类都强烈依赖于父类的实现。如果有新的需求需要添加一种新的行为,可能会影响到所有的鸭子子类。
  3. 可维护性差: 如果鸭子的某个子类需要修改继承的行为,就必须在子类中进行修改,可能导致代码的脆弱性和可维护性下降。
  4. 不灵活: 难以在运行时动态改变行为,因为行为是通过继承而来的,而不是可以随时替换的组件。

设计原则

封装变化

  • 识别应用程序中会发生变化的方面,并将其与保持不变的部分分离。
  • 将会变化的部分进行封装,以便以后可以修改或扩展变化的部分,而不影响那些保持不变的部分。
  • Program to an interface, not an implementation.

image.png

其他类型的对象可以重用我们的飞行和嘎嘎叫行为,因为这些行为不再被硬编码在我们的 Duck 类中。 我们可以添加新的行为,而无需修改任何现有的行为类或触及使用飞行行为的 Duck 类。

改进

image.png

image.png

image.png

image.png

我们在运行时改变行为:

image.png

定义

image.png

  1. 策略接口(Strategy Interface): 定义了所有支持的算法的通用接口。
  2. 具体策略(Concrete Strategy): 实现了策略接口,提供具体的算法实现。
  3. 上下文(Context): 包含一个对策略接口的引用,通常是通过该接口来调用具体的算法。上下文可以在运行时动态切换不同的策略。
  • 策略模式 意图:
  • 定义一族算法,将每个算法封装起来,并使它们可以互换使用。策略模式使得算法的变化独立于使用它的客户端。 也称为:
  • 策略模式 也被称为 Policy 模式