策略模式用于解决判断分支过多的问题,使代码变得简洁和优雅,
策略模式在多种方式在项目中落地,下面举例说明通过指定不同类型的订单使用策略模式执行不同的业务逻辑
文章参考自公众号:石杉的架构笔记
//通过注解中的value值来表示不同的分支,从而执行不同的业务逻辑
@Target({ElementType.TYPE}) @Retention(RetentionPolicy.RUNTIME) @Documented @Inherited public @interface HandlerType { String value(); }
-抽象处理器-定义子处理器要实现的行为
public abstract class AbstractHandler { public abstract String handle(OrderDTO dto); }
-子处理器1-实现抽相关处理器的行为1
@HandlerType(value = "1") @Component public class NomalHandler extends AbstractHandler{ @Override public String handle(OrderDTO dto) { return "normal"; } }
-子处理器2-实现抽相关处理器的行为2
@HandlerType(value = "2") @Component public class GroupHandler extends AbstractHandler{ @Override public String handle(OrderDTO dto) { return "group"; } }
-处理器上下文-根据不同条件映射到不同的处理器
public class HandleContext { private Map<String,Class> handlerMap; public HandleContext(Map<String,Class> handlerMap){ this.handlerMap=handlerMap; } public AbstractHandler getInstance(String type){ Class<? extends AbstractHandler> aClass = handlerMap.get(type); if (aClass==null) { throw new IllegalArgumentException(); } return SpringContextUtil.getBean(aClass); } }
@Component @SuppressWarnings("unchecked") public class HandlerProcessor implements BeanFactoryPostProcessor { @Override public void postProcessBeanFactory(ConfigurableListableBeanFactory configurableListableBeanFactory) throws BeansException { Map<String, Class> handlerMap = new HashMap<>(); //获取指定报下的所有类 ResourcePatternResolver resolver = new PathMatchingResourcePatternResolver(); MetadataReaderFactory metaReader = new CachingMetadataReaderFactory(); List<Class<?>> list = new ArrayList(); try { Resource[] resources = resolver.getResources("classpath*:designstrategy/demo/config/handler/*.class"); ClassLoader loader = ClassLoader.getSystemClassLoader(); for (Resource resource : resources) { MetadataReader reader = metaReader.getMetadataReader(resource); String className = reader.getClassMetadata().getClassName(); Class<?> clazz = loader.loadClass(className); HandlerType annotation = clazz.getAnnotation(HandlerType.class); // System.out.println("格式化前:"+clazz); class designstrategy.demo.config.handler.AbstractHandler System.err.println("格式化后:" + ClassUtils.getQualifiedName(clazz)); //获取所有接口 ClassUtils.getAllInterfaces(clazz); //判断是一个类是不是抽象类 boolean anAbstract = Modifier.isAbstract(clazz.getModifiers()); // System.err.println("判断一个类是不是抽象类:" + anAbstract);如果不是抽象类,添加到集合 if (!anAbstract) { list.add(clazz); } } System.out.println("集合" + list); //将类添加到Map中 for (Class<?> aClass : list) { Annotation[] annotations = aClass.getAnnotations(); // 这里有个坑 Annotation annotation = aClass.getAnnotation(HandlerType.class);获取到的annotation为null for (Annotation annotation : annotations) { if (annotation instanceof HandlerType) { String value = ((HandlerType) annotation).value(); handlerMap.put(value, aClass); System.out.println(value); } } } } catch (Exception e) { e.printStackTrace(); } HandleContext handleContext = new HandleContext(handlerMap); //将上下文添加到spring bean容器中 configurableListableBeanFactory.registerSingleton(HandleContext.class.getName(), handleContext); } }
@Component public class SpringContextUtil implements ApplicationContextAware { private static ApplicationContext applicationContext; @Override public void setApplicationContext(ApplicationContext applicationContext) throws BeansException { SpringContextUtil.applicationContext = applicationContext; } //获取applicationContext public static ApplicationContext getApplicationContext() { return applicationContext; } //通过name获取 Bean. public static Object getBean(String name) { return getApplicationContext().getBean(name); } //通过class获取Bean. public static <T> T getBean(Class<T> clazz) { return getApplicationContext().getBean(clazz); } //通过name,以及Clazz返回指定的Bean public static <T> T getBean(String name, Class<T> clazz) { return getApplicationContext().getBean(name, clazz); } }
@RestController @RequestMapping("/order") public class OrderController { @Autowired private OrderService orderService; @RequestMapping("/handle") public String handle(OrderDTO dto){ String str=orderService.handle(dto); System.out.println(str); return str; } }
6.service层
@Service public class OrderServiceImpl implements OrderService{ @Autowired private HandleContext handleContext; @Override public String handle(OrderDTO dto) { AbstractHandler handler = handleContext.getInstance(dto.getType()); return handler.handle(dto); } }
@Data public class OrderDTO { /** 订单类型 */ private String type; }
启动项目:使用postman分别测试以下两个接口
接口一:localhost:8080/order/hander?type=1
返回结果:normal
接口二localhost:8080/order/hander?type=2
返回结果:group
代码地址:https://github.com/AlenYang123456/design-strategy
原文:https://www.cnblogs.com/gabriel-y/p/11674639.html