介绍
定义算法家族,分别封装起来,让他们之间可以相互替换,此模式可以让算法的变化,不会影响到使用算法者。
作用
解决在有多种算法相似的情况下,使用 if…else 所带来的复杂和难以维护。
使用场景
- 如果在一个系统里面有许多类,它们之间的区别仅在于它们的行为,那么使用策略模式可以动态地让一个对象在许多行为中选择一种行为。
- 一个系统需要动态地在几种算法中选择一种。
- 如果一个对象有很多的行为,如果不用恰当的模式,这些行为就只好使用多重的条件选择语句来实现。
应用实例
背景
因为业务入库需求,需要开发一个PG的入库工具,能支持多种类型的入库需求,目前暂定为 【copy、upsert等】入库需求,后续可能会新增入库需求
分析
如果按常规逻辑开发,在代码中使用if else条件语句进行判断,每个if中为不同的入库逻辑,当有新的入库需求,则修改代码加入if判断,但当if过多会使代码可读性降低,稍有不慎可能改错逻辑产生新的bug,此时就想到了使用策略模式, 入库这个动作抽离出来,封装成接口,入库时只用提供入库表规则信息和入库文件信息,针对不同类型的数据基于入库模式接口分别实现不同的入库策略类,使用新增的入库模式类,此时使用新增策略类,但仍然需要在使用处new一个入库策略对象来使用,依旧需要修改现有代码,此时想到了使用工厂模式,传入相应的策略类型,由工厂来生产入库策略对象;工厂需要有生产对象信息才能生产对象,通过配置的方式提供入库策略类信息,通过反射技术动态加载策略类,新增入库策略只需基于入库模式接口开发,然后在配置中新增类路径即可,使程序的扩展性大大提高。
类图
代码样例
注:文章中代码经过脱密处理,不涉及公司业务
入库策略接口类
入库策略实现类
入库任务上下文对象
入库策略映射配置
入库任务上下文对象的工厂类
上下文对象工厂类的读入库模式配置方法,程序启动读取入库策略配置,使用反射创建对象并存储
上下文对象工厂类的getSchemaObject方法,可根据策略key值返会对应的入库任务上下文对象
使用策略上下文对象样例代码
优点
- 算法可以自由切换。
- 避免使用多重条件判断。
- 扩展性良好。
缺点
- 策略类会增多。
- 所有策略类都需要对外暴露。