策略模式结合Spring的优雅实现

1. 策略模式介绍

策略模式是一种行为模式,也是替代大量if else的利器(在项目设计中用的最多的)

一句总结就是: 定义一组算法类,将每个算法分别封装起来,让它们可以互相替换

举个例子🌰:

  1. 出行旅游: 乘坐飞机、乘坐火车、骑自行车、自己开私家车
  2. 交易方式: 信用卡、支付宝、微信
  3. 生成唯一ID策略: UUID、DB自增、DB+Redis、雪花算法、Leaf算法

上述场景都可以使用策略模式进行行为包装,供给外部使用

2. 策略模式的经典结构

  1. 上下文 (Context) 维护指向具体策略的引用, 且仅通过策略接口与该对象进行交流。
  2. 策略 (Strategy) 接口是所有具体策略的通用接口, 它声明了一个上下文用于执行策略的方法。
  3. 具体策略 (Concrete Strategies) 实现了上下文所用算法的各种不同变体。
  4. 客户端 (Client) 会创建一个特定策略对象并将其传递给上下文。 上下文则会提供一个设置器以便客户端在运行时替换相关联的策略。当上下文需要运行算法时, 它会在其已连接的策略对象上调用执行方法。 上下文不清楚其所涉及的策略类型与算法的执行方式。

在这里插入图片描述

图片来源:https://refactoringguru.cn/design-patterns/strategy

3. 优惠场景实战

3.1 面向过程开发

从头写到尾, 后续有新的优惠活动则继续添加新的if分支, 这种做法随着功能的不断累积, 往往会导致代码结构的复杂化, 进而使得整个系统变得难以维护和扩展。

在这里插入图片描述

3.2 使用策略模式改造代码

  1. 定义抽象策略接口
    在这里插入图片描述

  2. 定义具体策略类
    在这里插入图片描述在这里插入图片描述

  3. 定义策略工厂
    在这里插入图片描述

  4. Service层调用获取折扣后的价格
    在这里插入图片描述

3.3 上述实现的优点

  1. 将原本方法中的if语句优化掉
  2. 定义策略工厂,封装创建策略实现(算法),对客户端屏蔽具体的创建细节
  3. 有更好的隔离性与和扩展性

3.4 上述实现的缺点

  1. 添加一个策略算法实现,需要改动策略工厂中的代码,不符合开闭原则。

在这里插入图片描述

4. 使用 Spring 改造代码

要解决 3.4 中的缺点, 仅需将 static 代码块中消除即可。

可以使用 Spring 的特性实现, 使用ApplicationContext.getBeansOfType(Class<T> type)来获取容器中所有指定类型的Bean, 这样 map 中的值就有了, 而键则需要具体策略类来指定。

1. 改造抽象接口

  • 抽象策略接口中,新定义了key()接口,此接口用来标示算法的唯一性

在这里插入图片描述

2.改造实现类

  • 具体策略实现类,使用@Component 修饰,将对象本身交由 Spring 进行管理在这里插入图片描述
    在这里插入图片描述

3. 改造策略工厂

通过 InitializingBean 接口实现中调用 IOC 容器查找对应策略实现,随后将策略实现 key() 方法返回值作为 key, 策略实现本身作为 value 添加到 Map 容器中等待客户端的调用。
在这里插入图片描述

其中 DiscountStrategy中所有具体策略实现类如下, 分别是95折策略99折策略

在这里插入图片描述

这样就通过 Spring 的一些特性同时满足了开闭原则

后续添加具体策略类, 仅需实现DiscountStrategy接口即可, 不需要有额外的操作

这样就通过 Spring 的一些特性同时满足了开闭原则

若想要进一步优化代码, 可以使用枚举类作为 key()中的返回值, 作为 map 中的 key 能更方便阅读更优雅

  • 24
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

tiantian17)

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值