美文网首页
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