消除 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)@Documentedpublic @interface RestController {
String value() default "";
}
复制代码
配置类添加
@Configurationpublic 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,其他省略
@Compomentpublic 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 可以去掉。
@Servicepublic 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 挺好用,除非考虑扩展性很强的地方,否则不要过度设计。
评论