17-策略模式

策略模式

分析

旅游出行方式示意图

image-20221221195733839

分析:

  1. 实现某个目标的途径不止一条,可根据实际情况选择一条合适的途径

  2. 软件开发:

    • 多种算法,例如排序、查找、打折等

    • 使用硬编码(Hard Coding)实现将导致系统违背开闭原则,扩展性差,且维护困难

    • 可以定义一些独立的类来封装不同的算法,每一个类封装一种具体的算法\longrightarrow策略类

策略模式的定义

image-20221221200001069

image-20221221201048957

对象行为型模式

  • 又称为政策(Policy)模式
  • 每一个封装算法的类称之为策略(Strategy)类
  • 策略模式提供了一种可插入式(Pluggable)算法的实现方案
    • 往算法中灵活地增加算法

策略模式结构

image-20221221200111909

  • 完全符合开闭原则

策略模式包含以下3个角色:
  • Context==(环境类)==

  • Strategy(抽象策略类)

  • ConcreteStrategy(具体策略类)

典型的抽象策略类代码
1
2
3
public abstract class Strategy {
public abstract void algorithm(); //声明抽象算法
}
典型的具体策略类代码
1
2
3
4
5
6
public class ConcreteStrategyA extends Strategy {
//算法的具体实现
public void algorithm() {
//算法A
}
}
典型的环境类代码
1
2
3
4
5
6
7
8
9
10
11
12
13
public class Context {
private Strategy strategy; //维持一个对抽象策略类的引用

//注入策略对象
public void setStrategy(Strategy strategy) {
this.strategy= strategy;
}

//调用策略类中的算法
public void algorithm() {
strategy.algorithm();
}
}
典型的客户端代码片段
1
2
3
4
5
6
7
……
Context context = new Context();
Strategy strategy;
strategy = new ConcreteStrategyA(); //可在运行时指定类型,通过配置文件和反射机制实现
context.setStrategy(strategy);
context.algorithm();
……
实例类图

image-20221221200450612

image-20221221200500413

(1) MovieTicket:电影票类,充当环境类

(2) Discount:折扣类,充当抽象策略类

(3) StudentDiscount:学生票折扣类,充当具体策略类

(4) ChildrenDiscount:儿童票折扣类,充当具体策略类

(5) VIPDiscount:VIP会员票折扣类,充当具体策略类

(6) Client:客户端测试类

结果及分析
  1. 如果需要更换具体策略类,无须修改源代码,只需修改配置文件即可,完全符合开闭原则

配置文件代码
1
2
3
4
<?xml version="1.0"?>
<config>
<className>designpatterns.strategy.StudentDiscount</className>
</config>

Java SE中的布局管理

image-20221221200643103

容器中布局方法的切换:

  • FlowLayout:流布局
  • GridLayout:网格布局
  • 中间接口LayoutManager2:进行二次分类

模式优点

  • 提供了对开闭原则的完美支持,用户可以在不修改原有系统的基础上选择算法或行为,也可以灵活地增加新的算法或行为

  • 提供了管理相关的算法族的办法

  • 提供了一种可以替换继承关系的办法

    • 也可以用继承实现:

      image-20221221203733157

    • 以上继承关系实现存在的缺陷:破坏封装性——子类的客户端代码可能会看到不需要的其它方法

  • 可以避免多重条件选择语句

    • 比如:if-else
  • 提供了一种算法的复用机制,不同的环境类可以方便地复用策略类

    • 提高算法的保密性、安全性以及复用性

模式缺点

  • 客户端必须知道所有的策略类,并自行决定使用哪一个策略类

  • 将造成系统产生很多具体策略类

  • 无法同时在客户端使用多个策略类

模式适用环境

  • 一个系统需要动态地在几种算法中选择一种

  • 避免使用难以维护的多重条件选择语句

  • 不希望客户端知道复杂的、与算法相关的数据结构提高算法的保密性与安全性

课后思考

在策略模式中,一个环境类Context能否对应多个不同的策略等级结构?如何设计?

比如实际情景:飞机的多种起飞方式和多种飞行方式

image-20221221204729623

注意:区别于桥接模式

  • Copyright: Copyright is owned by the author. For commercial reprints, please contact the author for authorization. For non-commercial reprints, please indicate the source.
  • Copyrights © 2023-2024 Guijie Wang
  • Visitors: | Views:

请我喝杯咖啡吧~

支付宝
微信