Strategy 策略模式在实际项目中的使用

Strategy 策略模式在实际项目中的使用

引言

最近通读了《重构》这本书,其中讲到了在实际开发过程中不应该出现大量的 if…else 以及 switch…case 语句,这让我想起了自己之前做的一个项目。其中有部分代码,会使用非常多的 switch…case 语句来判断数据视图从而找到对应的处理类,而所有的处理类其实都是同一个接口的实现类。按照《重构》的指导,我决定使用策略模式(Strategy)来改造这一部分的代码。

策略模式

要实现策略模式,需要有三个要素,按《研磨设计模式》:

  1. Context:上下文,负责和具体的策略类交互。持有真正的策略模式。
  2. Strategy:抽象策略,可以是接口或抽象类,用于约束一系列具体的策略算法。
  3. ConcreteStrategy:策略的具体实现,即平级的各种算法的实现。

策略模式

具体实现的代码就不再贴出,这些网上都很容易找到,按照步骤一步一步的实现即可。希望深入了解重构和设计模式的话可以参考《重构-改善既有代码的设计》和《研磨设计模式》这两本书。

疑问

在实际实现的过程中发现,在 Context 中,还是需要根据类型来找到对应的策略实现类,但是如果这样做的话就仅仅是分散了实现算法,并没有达到真正的消除 switch…case 语句的目的。

解决方法

经过查找资料,学习总结他人的实现方法。我发现,在 Context 中,由于各种实现类都已经被分开,我们可以使用 Map<String, ConcreteStrategy> 的方式来替代 switch … case 语句。

将需要判断的类型当做 Key,具体的实现类作为 Value,这样的话,就能够达到在 Context 中消除 switch … case 的目的了。

具体实现

如何配置这个Map,有几种方法:

  1. 在配置文件中配置对应的类型和实现类,如:wechat=net.csdn.mp.WechatConcreteStratege,再根据反射,从配置文件中获取类型对应的属性后得到对应的实例。
  2. 同样使用反射。可以使用“惯例优于配置”的方式来对需要判断的类型名进行约束,如定义WechatFileUploadQQFileUploadZhiHuFileUpload的类型,根据规则找到对应的net.csdn.mp.WechatConcreteStratege等实现类,再获得对应实例。
  3. 同样使用反射。在各个实现类上添加各类型的注解,在策略类工厂中获取所有拥有该注解的实现类的实例,将类型及对应的实例放入Map中,再根据类型来获取该工厂的Map中对应的实例。
  4. 使用 Spring 的 Bean。定义一个 Bean,拥有一个 Map 的 Field。在该 Bean 初始化的时候即在 Map 中配置类型及对应实现类的 Bean。
  5. 使用表驱动法。利用一个Dictionary集合来维护目标对象与键值之间的映射关系。

总结

策略模式的目的是降低代码间的耦合,实现开闭原则。策略模式实现起来不难,使用的场景也较多。在使用策略模式之前可以考虑下是否可以使用 Replace Type Code with Subclasses 的方式来消除条件表达式,这是一种更简单的方式。

在使用策略模式过程中出现的疑问,是属于钻进了条件表达式的死胡同里,没有站在更高的角度去考虑其实现方式。

需要阅读更多优秀的代码,学习他人的思考方式,学习不同的代码实现。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值