美文网首页
Spring中使用策略模式解决多重判断

Spring中使用策略模式解决多重判断

作者: 墨兮之 | 来源:发表于2020-01-16 18:44 被阅读0次

    当我们需要使用多重判断解决不同业务时,为了提高代码的可扩展性,我们可以使用策略模式来替代多重if else。

    理解图

    如图 首先我们需要定义一个处理器的抽象类(也可以使用接口),让我们的具体处理器继承这个抽象类,这样我们便可以定义一个通用的接收变量,当我们需要某个具体的处理器时做一下转型即可,抽象类代码如下:

    /**
     * @description: 根据类型加载资源
     * @author: Aaron
     * @create: 2019-10-31 15:36
     */
    public abstract class TypeHandler {
        public abstract LinkBean handle(LinkBean bean);
    }
    

    除了继承抽象类作为实例接收器,我们还需要类型注解,在Spring中我们自己定义一些注解,来为一些处理类打上标识,这样的话我们便可以根据这些标识找到某个我们需要的具体的类,注解如下定义:

    /**
     * @description: 处理类型
     * @author: Aaron
     * @create: 2019-10-31 15:41
     */
    @Inherited
    @Retention(RetentionPolicy.RUNTIME)
    @Target(value = ElementType.TYPE) 
    @Documented
    public @interface TypeAnnotation {
        String value();
    }
    

    有了这注解和抽象类后,我们就可以定义具体的处理类了 比如,我创建两个不同的处理器类:

    @Component
    @TypeAnnotation("1")
    public class FristHandle extends TypeHandler {
    public LinkBean handle(LinkBean bean) {
    bean.setName("FristHandle");
      return bean;
    }
    }
    
    @Component
    @TypeAnnotation("2")
    public class TwoHandle extends TypeHandler {
    public LinkBean handle(LinkBean bean) {
    bean.setName(" TwoHandle");
      return bean;
    }
    }
    

    现在我们可以看到,我们已经有了两个处理器了,他们的注解分别被“1”和“2”标识。而此时呢我们需要用一个map来将这些类型和对应的处理器装起来,而在Spring中有一个getBeansWithAnnotation方法可以扫描被注解的类,我们可以用这个来得到map,然后再将map封装成一个处理器容器,我们只需要根据类型得到对应的类就行了。所以,首先我们创建一个可以承接map的处理器:

    /**
     * @description: 策略模式处理类
     * @author: Aaron
     * @create: 2019-10-31 18:01
     */
    public class HandlerContext {
        private Map<String, Object> handlerMap;
        public HandlerContext(Map<String, Object> handlerMap) {
            this.handlerMap = handlerMap;
        }
        public Object getInstance(String type) {
            Object clazz = handlerMap.get(type);
            if (clazz == null) {
                throw new IllegalArgumentException("输入的参数类型有问题:" + type);
            }
            return clazz;
        }
    }
    

    然后我们只需要扫描一遍注解,将结果封装在这个处理类对象中就行了。

        /**
         * 环节业务处理器
         */
        @Bean
        public HandlerContext getHandler(ApplicationContext applicationContext){
            Map<String,Object> handlerMap=new HashMap();
            //获得该注解下所有的bean
            Map<String, Object> beansWithAnnotation = applicationContext.getBeansWithAnnotation(TypeAnnotation.class);
            for (Map.Entry<String, Object> e : beansWithAnnotation.entrySet()) {
                Class<?> aClass = e.getValue().getClass();
                handlerMap.put(aClass.getAnnotation(SituationTypeAnnotation.class).value(),e.getValue());
            }
            return new HandlerContext(handlerMap);
        }
    

    到这里基本上就大功告成了,我们只要在具体的业务类中注入这个HandlerContext,就可以根据类型得到对应的处理器实例啦!

        /**
         * 业务处理器
         */
        @Autowired
        private HandlerContext handlerContext;
    
        @RequestMapping(value = "/getSituationResource",method = RequestMethod.GET)
        @ResponseBody
        public LinkBean getResource(@Valid @ModelAttribute LinkBean bean, BindingResult bindingResult){
            TypeHandler handler = (TypeHandler)handlerContext.getInstance("1");//得到“1”对应的处理器
             // handler  = (TypeHandler)handlerContext.getInstance("2");//得到“2”对应的处理器
            return  handler.handle(bean);
        }
    

    当我们需要扩展的时候,只需要添加对应的处理器3,处理器4 ......当然,别忘了类型!

    相关文章

      网友评论

          本文标题:Spring中使用策略模式解决多重判断

          本文链接:https://www.haomeiwen.com/subject/pjorbctx.html