消除 if-else 的方法有很多种,本文结合 spring 中 ArgumentResolver 的应用,提供一种优雅地方式。
先看 ArgumentResolver 的应用方式
public class UserArgumentResolver implements HandlerMethodArgumentResolver {
private static final String TOKEN_KEY = "token";
@Override
public boolean supportsParameter(MethodParameter parameter) {
return parameter.hasParameterAnnotation(LoginUser.class);
}
@Override
public Object resolveArgument(MethodParameter parameter,
ModelAndViewContainer mavContainer,
NativeWebRequest webRequest,
WebDataBinderFactory binderFactory) throws Exception {
// 通过session取userid
String token = webRequest.getHeader(TOKEN_KEY);
User user = null;
// 从redis中获取user json
// user = JSON.parse(redis.get(token),User.class);
return user;
}
}
复制代码
controller 需要注入参数的地方
@RequestMapping(value = "/doSth", method = RequestMethod.POST)
public String feed(@LoginUser User user) {
System.out.println("userId: " + JSON.toJsonString(user));
return "success";
}
复制代码
声明注解 LoginUser
@Target(ElementType.TYPE,ElementType.PARAMETER)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface RestController {
String value() default "";
}
复制代码
配置类添加
@Configuration
public class WebConfiguration implements WebMvcConfigurer {
@Override
public void addArgumentResolvers (List<HandlerMethodArgumentResolver> resolvers) {
resolvers.add(new UserArgumentResolver());
}
}
复制代码
有多个 ArgumentResolver 在 WebConfiguration 中配置即可。
if-else 消除
常用代码 如交通方式有 bike, bus,subway,train,plan
if (bike) {
} else if (bus) {
} else if (subway) {
} else if (train) {
} else if (plan) {
}else {
}
复制代码
编写不同的 reslover
定义统一的接口
public interface TrafficResolver {
boolean support(String type);
Object resolver(Object argument);
}
复制代码
定义实现类 BusTrafficResolver,其他省略
@Compoment
public class BusTrafficResolver implements TrafficResolver{
@Override
public boolean support (String type) {
return "BUS".equals(type);
}
@Override
public Object resolver (Object argument) {
// doSth
return "bus resolver";
}
}
复制代码
真正消除 if-else 的服务类
List<TrafficResolver> 若没有 bean 则需要 required 比提供默认值 new ArrayList<>() ,有 bean 可以去掉。
@Service
public class TrafficService {
// required = false
@Autowired(required = false)
List<TrafficResolver> trafficResolverList = new ArrayList<>();
public Object traffic(String type,Object argument){
System.out.printf("trafficResolverList "+trafficResolverList.size());
TrafficResolver resolver = getFirstResolver(type);
if(resolver!=null){
return resolver.resolver(argument);
}
return "traffic not find. type: "+type;
}
private TrafficResolver getFirstResolver(String type){
TrafficResolver resolver = trafficResolverList.stream()
.filter(item -> item.support(type))
.findFirst()
.orElse(null);
return resolver;
}
}
复制代码
通过此种方式完成了对 if-else 调用类的解耦,实现了高扩展性。遵循了面向修改关闭,面向扩展开放的原则。
消除 if-else 完成,当然可以用注解的方式,通过注解类型判断是否支持。
其实 if-else 挺好用,除非考虑扩展性很强的地方,否则不要过度设计。
评论