admin管理员组

文章数量:1794759

设计模式——Strategy(策略)模式

设计模式——Strategy(策略)模式

目录
  • 前言
  • 1 定义
  • 2 适用性
  • 3 结构
    • 3.1 结构图
    • 3.2 参与者
  • 4 实际应用举例
    • 4.1 Context——List列表和StuContext
    • 4.2 具体策略:ConcreteStrategyA和ConcreteStrategyB
    • 4.3 测试demo
  • 5 总结
  • 参考文献

前言

当我们对一个对象的某个操作,比如文本分析或者对象排序有多种算法,但是如果硬编码进它们的类中,将导致出现后续扩展困难,复杂度较高等。策略模式提出了一种方法解决这种情况。

1 定义

Strategy(策略)模式:定义一系列算法,并把它们独立封装到类中,使它们可以相互替换,独立于使用它们的客户而变化。

2 适用性
  • 当你使用的对象中,有多种可选择算法,并希望在运行时动态改变。
  • 当你有许多仅在行为上有不同的相似类时。
  • 如果你使用的算法在对象和上下文中关联不密切,你可以抽象出算法与对象隔离开。
3 结构 3.1 结构图

策略模式结构图如下:

3.2 参与者
  • Context:客户使用的对象,可以使用多种策略执行一个行为。通常包含一个指向策略实例的指针。
  • Strategy:策略接口,定义了一系列相似策略的抽象公共部分方法。
  • ConcreteStrategyA,ConcreteStrategyB和ConcreteStrategyC:具体的策略类,封装了特定的策略方法。由context进行调用。
4 实际应用举例

java中排序接口Comparator就是一种策略模式,由我们根据我们的对象去实现不同的排序策略。

4.1 Context——List列表和StuContext

LIst可以作为我们的Context,里边存储的对象StuContext是需要根据不同策略进行排序的内部数据。 以ArrayList为例,内部排序方法如下: 可见是通过传入策略接口,来实现对不同策略的支持。 StuContext定义如下:

/** * 策略支持的对象类 */ @Data @NoArgsConstructor @AllArgsConstructor public class StuContext { //名字 private String stuName; //平均分数 private int avgScore; //数学分数 private int mathSCore; @Override public String toString() { return "StuContext{" + "stuName='" + stuName + '\\'' + ", avgScore=" + avgScore + ", mathSCore=" + mathSCore + '}'; } }

就是定义一个实体,包含内部属性:名称、平均成绩和数学成绩。

4.2 具体策略:ConcreteStrategyA和ConcreteStrategyB

定义具体的排序策略:

  • 平均成绩降序排列:ConcreteStrategyA
  • 数学成绩降序排列:ConcreteStrategyB

分别定义如下:

/** * 策略A——按照平均分进行排名 */ public class ConcreteStrategyA implements Comparator<StuContext> { @Override public int compare(StuContext o1, StuContext o2) { return o2.getAvgScore() - o1.getAvgScore(); } } /** * 策略B——按照数学成绩排名 */ public class ConcreteStrategyB implements Comparator<StuContext> { @Override public int compare(StuContext o1, StuContext o2) { return o2.getMathSCore() - o1.getMathSCore(); } } 4.3 测试demo

代码如下: 执行结果:

5 总结

当需要在运行时经常改变算法,同时又希望算法和对象进行隔离,减少耦合,可以借鉴策略模式。

参考文献

[1]. 《设计模式》

本文标签: 模式策略strategy