前言
最近刚看完《设计模式之禅》,在写代码前总是想着能不能尝试用上一些设计模式。前几天看到一篇公众号推文利用策略模式来优化过多的if else代码,正好符合目前我面临的一个场景,作者使用一个枚举类来维护所有的策略,这样的话,没增加一个策略,都要去枚举类里增加相应的枚举常量,不太符合“开闭原则”。同时,随着策略的增加,这个枚举类源码的理解性也会变得越来差,也比较难维护。我通过注解+反射和策略模式做了重构,这样一来增加一个策略之后,只需要放到被扫描的包下,就会被自动识别和使用,比枚举的方式更具扩展性,也更加的符合“开闭原则”。设计模式相关的资料网上很多,我就不再介绍什么是策略模式,直接介绍如何实现。
场景描述
平时大家可能都会写这样的代码,如果条件过多的话逻辑就比较混乱,也容易出错。比如我面临的场景:需要访问数十个API接口,对每个API接口返回的数据做不同的处理,如果按如下方式实现的话,我就要写数十个if else,增加一个API时又要来增加一个if else 即难以维护,阅读性也很差。
if(a){
}else if(b){
}else if(c){
}else{
}
策略模式优化
优化的大致思想为:首先把每个if else里逻辑抽取到各实现类中作为策略,并使用自定义注解给每个策略命名;然后,通过反射机制扫描使用该注解的所有类,放入锦囊(Map)中;最后,根据策略名(key),取出相应的策略执行相应的逻辑。
策略实现
- 注解实现
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface DataSourceType {
// 策略名,在我的场景中是API的类型
String value() default "";
}
- 策略抽象类
import java.util.Map;
public interface DataSourceStrategy {
// 每个策略是逻辑实现
Map<String,Object> connect(Map<String,String> params);
}
- 策略实现类
import com.uniplore.restdata.core.datasource.DataSourceStrategy;
import com.uniplore.restdata.core.datasource.DataSourceType;
import org.springframework.stereotype.Service;
import java.util.Map;
@Service
@DataSourceType("aliPay"