标签:play 注释 ted 映射关系 方法 项目启动 efault equals 图片
代码中有时候会堆积很多if-else,后续有条件变动,需要回过头来对if-else对应的代码块进行修改,这违反了开闭原则。有没有一种方式重构这类代码呢?网上浏览到一篇博客,感觉方式很好,特记录下来,还是用原博客的例子(根据不同条件处理订单)。
通过策略模式+注解的方案重构if-else代码块。
思路是:
---
订单类:
@Data public class Order { /** * 订单来源 */ private String source; /** * 支付方式 */ private String payMethod; /** * 订单编号 */ private String code; /** * 订单金额 */ private BigDecimal amount; public static Order newInstance(String source,String payMethod) { Order order = new Order(); order.setSource(source); order.setPayMethod(payMethod); return order; } }
策略接口:
public interface OrderHandler { void handle(Order order); }
定义注解:
@Target(ElementType.TYPE) @Retention(RetentionPolicy.RUNTIME) @Documented @Service public @interface OrderHandlerType { String source() default "mobile"; String payMethod() default "wechat"; }
实现一系列策略:
//file: PcWechatOrderHandler.java //处理pc-wechat订单 @OrderHandlerType(source = "pc",payMethod = "wechat") public class PcWechatOrderHandler implements OrderHandler { @Override public void handle(Order order) { System.out.println("处理PC-WECHAT订单"); } } //file: PcAlipayOrderHandler.java //处理pc-alipay订单 @OrderHandlerType(source = "pc",payMethod = "alipay") public class PcAlipayOrderHandler implements OrderHandler { @Override public void handle(Order order) { System.out.println("处理PC-ALIPAY订单"); } }
Service类:
@Service public class OrderService { private Map<OrderHandlerType, OrderHandler> orderHandleMap; @Autowired public void setOrderHandleMap(List<OrderHandler> orderHandlers) { orderHandleMap = orderHandlers.stream().collect( Collectors.toMap( orderHandler -> AnnotationUtils.findAnnotation(orderHandler.getClass(), OrderHandlerType.class), orderHandler -> orderHandler, (v1, v2) -> v1 ) ); } // 这个方法给控制器用,处理实际的业务逻辑 public void orderService(Order order) { // 前置的一些处理 // 策略类的一些处理 Annotation anno = getAnno(order.getSource(), order.getPayMethod()); OrderHandler orderHandler = orderHandleMap.get(anno); orderHandler.handle(order); // 后置的一些处理 } // 这个方法,根据业务条件,获取对应的注解 private Annotation getAnno(String source, String payMethod) { Set<OrderHandlerType> orderHandlerTypes = orderHandleMap.keySet(); for (OrderHandlerType i : orderHandlerTypes) { if (i.source().equals(source) && i.payMethod().equals(payMethod)) { return i; } } System.out.println("will throw not support exception ..."); throw new RuntimeException("not support.."); } }
controller类:
@RestController public class OrderController { @Autowired private OrderService os; @GetMapping("/order") public String order(@RequestParam(name = "t", defaultValue = "pc") String type, @RequestParam(name = "p", defaultValue = "wechat") String payMethod) { Order order = Order.newInstance(type, payMethod); os.orderService(order); return "success"; } }
---
[啰嗦一下,策略模式通常是解决同样的问题,不同的计费策略,都是解决计费的问题。命令模式通常是解决不同的问题]
标签:play 注释 ted 映射关系 方法 项目启动 efault equals 图片
原文地址:https://www.cnblogs.com/luohaonan/p/13539581.html