工作中经常会有一些swich case或者if else的情况。一般这种情况一开始可能只有几个,但是几次迭代之后可能就会有非常多。代码不易维护而且代码乱糟糟的。
我在工作中就遇到了这种情况。大致的业务就是我们需要对接很多家公司,要为每家公司回传一些数据。每家公司的接口和回传方式都不一样。之前的代码是为每一家公司定义一个枚举。然后在回传的时候根据枚举用swich/case来判别回传方式。这样的结果就是对接的公司越来越多,代码也越来越长。一个函数长度达到了两百多行。非常难受。
方案后来终于受不了了想拿他开刀。这个问题不难,关键解决方案就是多态+反射。多态就是定义一个接口一个notify函数。然后每一家公司实现这个接口就可以了。反射的话其实用不到JDK的反射,spring自带反射,用名字就可以得到这个类的实例。废话不多说下面上代码。
枚举首先要定义一个枚举,每一种情况一个字段,注意,枚举要有一个属性,beanName,方便反射的时候获取实例。这里把名字都简化了。
@Getter
@AllArgsConstructor
public enum SomeEnum {
NONE(0, ""),
A(1, "aServiceImpl"),
B(2, "bServiceImpl"),
C(3, "cServiceImpl"),
D(4, "dServiceImpl"),
// 公司的这里有二十多个,现在就简略一下。
;
private int type;
private String beanName;
}
接口
第二步,定义一个接口。
public interface BaseService {
boolean doSomething(String a);
}
实现
第三步,上面每一个枚举都添加一个类实现这个接口,注意命名方式和beanName相同,因为spring默认的bean名字是第一个小写,所以实现类还是遵循命名规范用大写。而且一定要打上@Service
@Service
@Slf4j
public class AServiceImpl implements BaseService {
@Override
public boolean doSomething(String a) {
// 业务逻辑写在这里
return true;
}
}
多态
第四步,就差这步了。把原来的switch/case全删掉。换上下面这几行代码。
@Autowired
private ApplicationContext applicationContext;
BaseService service = (BaseService) applicationContext.getBean(someEnum.getBeanName());
result = service.doSomething("xxx");
总结
原本几百行的代码在这里就变得十分清爽了。
如果现在要添加一个公司,只需要添加一个枚举字段,添加一个类实现base接口,就可以了。做到和现有代码解耦,代码也更容易理解了。对于大量if/else的情况也是类似来处理。