先说明情景:以订单处理为例,大体分PC端处理和mobile端处理,PC端分为扫码支付、信用卡支付,mobile端分为微信、支付宝处理。。。等等。
那么如何避免if-else呢?
策略模式注解实现
首先是订单Order类,和OrderService。
@Data public class Order {
private String source;
private String payMethod;
private String code;
private BigDecimal amount; }
|
假如对于不同来源(pc端、移动端)的订单需要不同的逻辑处理。项目中一般会有OrderService这样一个类,如下,里面有一坨if-else的逻辑,目的是根据订单的来源的做不同的处理。
@Service public class OrderService {
public void orderService(Order order) { if(order.getSource().equals("pc")){ }else if(order.getSource().equals("mobile")){ }else { } } }
|
大致的类图是这样的:
1.首先定义一个OrderHandler接口,此接口规定了处理订单的方法。
public interface OrderHandler { void handle(Order order); }
|
2.定义一个OrderHandlerType注解,来表示某个类是用来处理何种来源的订单。
@Target(ElementType.TYPE) @Retention(RetentionPolicy.RUNTIME) @Documented @Service public @interface OrderHandlerType { String source(); String payMethod(); }
|
但是我们还需要order的来源和支付方式与OrderHandlerType注解关联起来了。所以,现在我们就实现这么一个类
public class OrderHandlerTypeImp implements OrderHandlerType {
private String source; private String payMethod;
OrderHandlerTypeImp(String source, String payMethod) { this.source = source; this.payMethod = payMethod; }
@Override public String source() { return source; }
@Override public String payMethod() { return payMethod; }
@Override public Class<? extends Annotation> annotationType() { return OrderHandlerType.class; }
@Override public int hashCode() { int hashCode = 0; hashCode += (127 * "source".hashCode()) ^ source.hashCode(); hashCode += (127 * "payMethod".hashCode()) ^ payMethod.hashCode(); return hashCode; }
@Override public boolean equals(Object obj) { if (!(obj instanceof OrderHandlerType)) { return false; } OrderHandlerType other = (OrderHandlerType) obj; return source.equals(other.source()) && payMethod.equals(other.payMethod()); } }
|
3.接下来就是实现pc端和移动端订单处理各自的handler,并加上我们所定义的OrderHandlerType注解。
@OrderHandlerType(source = "pc", payMethod = "cardPay") public class PCHandler implements OrderHandler { @Override public void handle(Order order) { System.out.println("处理PC端, cardPay订单!!"); } }
@OrderHandlerType(source = "mobile", payMethod = "weChat") public class WeChatHandler implements OrderHandler { @Override public void handle(Order order) { System.out.println("微信支付处理了订单"); } }
@OrderHandlerType(source = "mobile", payMethod = "airPay") public class AirPayHandler implements OrderHandler { @Override public void handle(Order order) { System.out.println("支付宝处理了订单"); } }
|
4.以上准备就绪后,就是向spring容器中注入各种订单处理的handler,并在OrderService.orderService方法中,通过策略(订单来源)去决定选择哪一个OrderHandler去处理订单。我们可以这样做:
@Service public class OrderService {
private Map<OrderHandlerType,OrderHandler> orderHandlerMap;
@Autowired public void setOrderHandleMap(List<OrderHandler> orderHandlers) { orderHandlerMap = orderHandlers.stream().collect( Collectors.toMap(orderHandler -> AnnotationUtils.findAnnotation(orderHandler.getClass(), OrderHandlerType.class), v -> v,(v1, v2) -> v1)); }
public void orderService(Order order) { System.out.println("前置处理方法"); OrderHandlerType orderHandlerType = new OrderHandlerTypeImp(order.getSource(), order.getPayMethod()); OrderHandler orderHandler = orderHandlerMap.get(orderHandlerType); orderHandler.handle(order);
System.out.println("后置处理方法"); } }
|
5、下面我们进行测试
编写单元测试:
@SpringBootTest class StrategydemoApplicationTests { @Autowired private OrderService orderService;
@Test public void test(){ Order order = new Order(); order.setSource("mobile"); order.setPayMethod("airPay"); order.setAmount(new BigDecimal(200)); order.setCode("1020202020"); orderService.orderService(order); } }
|
测试结果:
代码地址:https://gitee.com/ellisonpei/designer