当我们需要使用多重判断解决不同业务时,为了提高代码的可扩展性,我们可以使用策略模式来替代多重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 ......当然,别忘了类型!
网友评论