当前位置: 移动技术网 > IT编程>开发语言>Java > 尽可能的“消除”代码中繁琐的if..else

尽可能的“消除”代码中繁琐的if..else

2020年07月16日  | 移动技术网IT编程  | 我要评论

当我们写代码时,肯定会碰到if...else语句,但是过多的if...else语句会让代码可读性变差,也不利于扩展,虽然自己写代码一时爽,若是交由别人维护,不免就会喷嚏连天,平时呢代码中的if...else语句大多数长这样

public String handleOrder(OrderDto dto) {
         if("团购".equals(dto.getType())) {
             return "处理团购订单";
         }else if("单点".equals(dto.getType())) {
             return "处理单点订单";
         }else if("外卖".equals(dto.getType())) {
             return "处理外卖订单";
         }else {
             return null;
         }
    }

比如根据订单的类型,选择怎么处理订单,这是传统实现,那么今天给大家带来用策略模式“消除”if...else

整体思路如下:

  1. 统一处理接口
  2. 自定义注解
  3. 利用spring扫描自定义注解,生成具体的策略模式所需上下文,并注册到spring容器中
  4. 具体处理类实现

一、统一处理接口

1、将所有的处理类抽象出来

public abstract class AbstractHandler {

        abstract public String handle(); 

}

2、每个选择项实现具体的处理方法handle

@Component
       @HandlerType("201")

public class TuanGouHandler extends AbstractHandler{

       @Override

       public String handle(){

       //具体业务逻辑实现

       }

}

有多少个选择项,就实现多少个AbstractHandler,并且每个实现类都必须注册到spring容器中,所以用@Component注解,@HandlerType("201")注解用来标识是哪个处理类

二、自定义注解

1、自定义注解

     @Target(ElementType.TYPE)
            @Retention(RetentionPolicy.RUNTIME)
            @Documented
            @Inherited
            public @interface HandlerType {
                   String value();
             }

三、利用spring扫描自定义注解,生成具体的策略模式所需上下文,并注册到spring容器中

@Component
public class HandlerProcessor implements BeanFactoryPostProcessor {

@SuppressWarnings({ "unchecked", "rawtypes" })
    @Override
    public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
        Map<String, Class> map = new HashMap<String, Class>();
        //classScanner是一个工具类,用来扫描所有在包下注解的实现
        //具体是用来扫描带注解HandlerType的处理类
        //将处理类注解HandlerType的value作为map的key,具体的Class作为value
        //handlerContext.getInstance()方法则会返回具体的处理类
        ClassScanner classScanner = new DefaultClassScanner();
        classScanner.scanByAnno(Arrays.asList("具体包名"), HandlerType.class).forEach(
                aClass -> {
                    //获取注解的value值,放入map

                   //上文的201作为key,value则为TuanGouHandler.class,绑定type的具体实现类
                    String value = ((HandlerType) aClass.getAnnotation(HandlerType.class)).value();
                    map.put(value, aClass);
                }
        );
        HandlerContext handlerContext = new HandlerContext(map);
        //注册handlerContext到spring容器,autowired才会有效果
        beanFactory.registerSingleton(handlerContext.getClass().getName(), handlerContext);
    }

}

ClassScanner是一个开源的工具类,如何获取请看这里 https://blog.csdn.net/weixin_34218890/article/details/92044693

HandlerContext 则存储相应的type和class

@SuppressWarnings({"rawtypes"})
public class HandlerContext {
    private Map<String, Class> handlerMap = new HashMap<String, Class>();
    
    public HandlerContext(Map<String, Class> handlerMap) {
        this.handlerMap = handlerMap;
    }
    
    public AbstractHandler getInstance(String type) {
        Class class1 = handlerMap.get(type);
        return (AbstractHandler) BeanUtil.getBean(class1);
    }
}

BeanUtil是一个通过className获取在spring中的bean工具类

@Component
@SuppressWarnings({"unchecked", "static-access", "rawtypes"})
public class BeanUtil implements BeanFactoryAware {
    
    private static BeanFactory beanFactory;

    @Override
    public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
        this.beanFactory = beanFactory;
    }
    
    public static Object getBean(Class className) {
        return beanFactory.getBean(className);
    }

}

HandlerProcessor 和 BeanUtil 一定要加上注解@Component,才会被spring扫描到

OK,接下来再你的service加上以下两句代码就搞掂了

    @Autowired
    HandlerContext handlerContext;

    public String handleOrder(OrderDto dto) {

         AbstractHandler handler = handlerContext.getInstance(dto.getType());
         return handler.handle(dto).
    }

整个思路就是用spring的钩子功能,BeanFactoryPostProcessor 是spring在容器初始化时对外暴露的扩展点,也就是说我们可以通过重写postProcessBeanFactory方法,实现我们自己所需要的功能,并可以在spring里初始化一些我们自己的东西,最终通过map将type与具体的处理类关联起来,每个处理类的HandlerType不一样,于是处理方法也就变得具体化了

 

 

本文地址:https://blog.csdn.net/Home_Bro123/article/details/107340102

如对本文有疑问, 点击进行留言回复!!

相关文章:

验证码:
移动技术网