Spring小技巧之设计模式

责任链模式

模式定义

  • 该模式在《图解设计模式》的第14章节《Chain of Responsibility模式》有详细的介绍。简单来说:当一个对象需要交给多个处理类依次处理的时候就可以用责任链模式,Servlet Filter、Spring 拦截器链都是这一模式的实际应用,在订单履约等业务场景中也经常使用到。

示例代码

  • OrderCreatedBaseHandler:责任链顶层接口定义类,所有处理器都实现该接口。

    package com.wwq.test;
    
    /**
     * 创建订单责任链接口
     */
    public interface OrderCreatedBaseHandler {
    
        /**
         * 运行消息处理
         */
        void run(Order order);
    
        /**
         * 是否执行</br>
         * 子类重写该方法,可根据配置开关,来确定是否执行 run 方法
         */
        default boolean isRun(Order order){
            return true;
        }
    
    }
    
  • OrderCreatedOperate:责任链执行器类,是整个责任链的管理容器和启动入口。利用Spring批量注入接口实现类为List的机制串联整个链条。

    package com.wwq.test;
    
    /**
     * 责任链执行器,运行所有 OrderCreatedBaseHandler 实现类
     */
    @Component
    public class OrderCreatedOperate {
    
        /*
         * 注入全部处理器
         */
        @Autowired
        private List<OrderCreatedBaseHandler>  baseOrderCreatedHandles;
    
        /**
         * 运行消息处理
         * @param orderCreatedMessage 订单创建消息
         */
        public void run(Order order) {
            for(OrderCreatedBaseHandler handler : baseOrderCreatedHandles){
               if(handler.isRun(order)){
                   handler.run(order);
               }
            }
        }
        
    }
    
  • 各个责任链处理,可通过@Order注解调整他们的执行顺序。

    package com.wwq.test;
    
    /**
     * 创建订单处理器
     */
    @Slf4j
    @Component
    public class OrderCreatedHandler implements OrderCreatedBaseHandler {
    
        public void run(OrderCreatedMessage orderCreatedMessage){
            // TODO 创建订单
        }
        
    }
    
    package com.wwq.test;
    
    /**
     * 积分处理器
     */
    @Slf4j
    @Component
    public class PointHandler implements OrderCreatedBaseHandler {
    
        public void run(OrderCreatedMessage orderCreatedMessage){
            // TODO 积分抵扣和发送
        }
        
    }
    
    package com.wwq.test;
    
    /**
     * 物流处理器
     */
    @Slf4j
    @Component
    public class LogisticsHandler implements OrderCreatedBaseHandler {
    
        public void run(OrderCreatedMessage orderCreatedMessage){
            // TODO 处理物流流程信息
        }
        
    }
    
    package com.wwq.test;
    
    /**
     * 商品库存处理器
     */
    @Slf4j
    @Component
    public class StockHandler implements OrderCreatedBaseHandler {
    
        public void run(OrderCreatedMessage orderCreatedMessage){
            // TODO 库存扣减
        }
        
    }
    
  • 如果想各个处理器并行执行,可以使用 CompletableFuture.runAsync() 提交异步任务。

    package com.wwq.test;
    
    /**
     * 责任链执行器,运行所有 OrderCreatedBaseHandler 实现类
     */
    @Component
    public class OrderCreatedOperate {
    
        /*
         * 责任链执行线程池
         */
        @Autowired
        @Qualifier("orderCreatedTaskExecutor")
        private Executor orderCreatedTaskExecutor;
    
        /*
         * 注入全部处理器
         */
        @Autowired
        private List<OrderCreatedBaseHandler>  baseOrderCreatedHandles;
    
        /**
         * 运行消息处理
         * @param orderCreatedMessage 订单创建消息
         */
        public void run(Order order) {
    
            /*
             * 收集 Future
             */
            List<CompletableFuture<?>> futures = new ArrayList<>();
    
            /*
             * 异步执行每个处理器
             */
            for(OrderCreatedBaseHandler handler : baseOrderCreatedHandles){
                futures.add(CompletableFuture.runAsync(() -> {
                    if(handler.isRun(order)){
                        handler.run(order);
                    }
                }, orderCreatedTaskExecutor));
            }
    
            /*
             * 等待所有异步任务全部执行完毕
             */
            CompletableFuture.allOf(futures.toArray(new CompletableFuture[0])).join();
        }
    
    }
    

策略模式模式

模式定义

  • 该模式在《图解设计模式》的第10章节《Strategy模式》有详细的介绍。当需要根据某种条件整体替换运算逻辑时就可以使用策略模式,在支付渠道、文件解析、报表导出、优惠计算等场景都有应用。

示例代码

  • 策略接口定义
    	public interface PayStrategy {
    	    // 渠道标识
    	    String getChannel();
    	    // 支付逻辑
    	    void pay(BigDecimal amount);
    	}
    
  • 策略实现
    @Component
    public class AliPayStrategy implements PayStrategy {
        @Override
        public String getChannel() {
            return "ALI";
        }
        @Override
        public void pay(BigDecimal amount) {
            System.out.println("支付宝支付:" + amount);
        }
    }
    
    @Component
    public class WxPayStrategy implements PayStrategy {
        @Override
        public String getChannel() {
            return "WX";
        }
        @Override
        public void pay(BigDecimal amount) {
            System.out.println("微信支付:" + amount);
        }
    }
    
  • 策略工厂
    @Service
    public class PayStrategyFactory {
        // 自动注入全部策略实现
        private final Map<String, PayStrategy> strategyMap;
    
        @Autowired
        public PayStrategyFactory(List<PayStrategy> payStrategies) {
            this.strategyMap = new HashMap<>();
            for(PayStrategy strategy : payStrategies){
                strategyMap.put(strategy.getChannel(), strategy);
            }
        }
    
        // 根据渠道获取对应策略
        public PayStrategy getStrategy(Integer channel) {
            return strategyMap.get(channel);
        }
    }
    
  • 使用策略
    @Autowired
    private PayStrategyFactory factory;
    
    public void test() {
        PayStrategy ali = factory.getStrategy("ALI");
        ali.pay(new BigDecimal("100"));
    }
    
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值