写点什么

项目中如何优雅的消除 if-else

作者:Rubble
  • 2022 年 4 月 18 日
  • 本文字数:1631 字

    阅读完需:约 5 分钟

消除 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 挺好用,除非考虑扩展性很强的地方,否则不要过度设计。

用户头像

Rubble

关注

还未添加个人签名 2021.06.01 加入

还未添加个人简介

评论

发布
暂无评论
项目中如何优雅的消除if-else_4月日更_Rubble_InfoQ写作平台