码迷,mamicode.com
首页 > 其他好文 > 详细

if-else Terminator

时间:2020-08-25 18:47:02      阅读:79      评论:0      收藏:0      [点我收藏+]

标签:play   注释   ted   映射关系   方法   项目启动   efault   equals   图片   

代码中有时候会堆积很多if-else,后续有条件变动,需要回过头来对if-else对应的代码块进行修改,这违反了开闭原则。有没有一种方式重构这类代码呢?网上浏览到一篇博客,感觉方式很好,特记录下来,还是用原博客的例子(根据不同条件处理订单)。

通过策略模式+注解的方案重构if-else代码块。

思路是:

  1. 编写策略接口,
  2. 定义注解,
  3. 实现一系列策略类,通过注解注释策略类,
  4. 项目启动,建立map保存注解和策略类的映射关系。
  5. 当处理业务时候,根据业务信息获取注解,通过上面提到的map获取到对应的策略类进行处理。

---

订单类:

技术图片
@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;
    }
}
View Code

 

策略接口:

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";
    }

}
View Code

 

 

---

[啰嗦一下,策略模式通常是解决同样的问题,不同的计费策略,都是解决计费的问题。命令模式通常是解决不同的问题]

if-else Terminator

标签:play   注释   ted   映射关系   方法   项目启动   efault   equals   图片   

原文地址:https://www.cnblogs.com/luohaonan/p/13539581.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!