Spring小技巧之设计模式

Spring小技巧之设计模式

责任链模式

模式定义

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

示例代码

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

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

    java 复制代码
    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注解调整他们的执行顺序。

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

    java 复制代码
    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模式》有详细的介绍。当需要根据某种条件整体替换运算逻辑时就可以使用策略模式,在支付渠道、文件解析、报表导出、优惠计算等场景都有应用。

示例代码

  • 策略接口定义

    java 复制代码
    	public interface PayStrategy {
    	    // 渠道标识
    	    String getChannel();
    	    // 支付逻辑
    	    void pay(BigDecimal amount);
    	}
  • 策略实现

    java 复制代码
    @Component
    public class AliPayStrategy implements PayStrategy {
        @Override
        public String getChannel() {
            return "ALI";
        }
        @Override
        public void pay(BigDecimal amount) {
            System.out.println("支付宝支付:" + amount);
        }
    }
    java 复制代码
    @Component
    public class WxPayStrategy implements PayStrategy {
        @Override
        public String getChannel() {
            return "WX";
        }
        @Override
        public void pay(BigDecimal amount) {
            System.out.println("微信支付:" + amount);
        }
    }
  • 策略工厂

    java 复制代码
    @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);
        }
    }
  • 使用策略

    java 复制代码
    @Autowired
    private PayStrategyFactory factory;
    
    public void test() {
        PayStrategy ali = factory.getStrategy("ALI");
        ali.pay(new BigDecimal("100"));
    }
相关推荐
岭南灯火6 小时前
前端通用交互式几何编辑器的开发经验
前端·设计模式·架构
岭南灯火6 小时前
前端通用交互式几何编辑器的设计法则 7 - 设计模式与原则
前端·设计模式·架构
岭南灯火6 小时前
前端通用交互式几何编辑器的设计法则 4 - 绘制、悬停与编辑
前端·设计模式·架构
岭南灯火6 小时前
前端通用交互式几何编辑器的设计法则 6 - 配套设施与工程化
前端·设计模式·架构
岭南灯火7 小时前
前端通用交互式几何编辑器的设计法则 5 - 辅助元素的设计
前端·设计模式·架构
堕落年代12 小时前
Ollama CPU 推理大提示词优化实测报告(细致化数据版)
java·后端·spring
cfm_291413 小时前
基于OAuth2.0实现微服务SSO单点登录
后端·spring·微服务·架构
攻城有术13 小时前
专项攻克-springcloud及其组件
后端·spring·spring cloud
叶总没有会14 小时前
5.1知识库概念进阶
java·人工智能·spring·阿里云·ai·原型模式
砍材农夫16 小时前
物联网实战|Spring Boot MQTT平台 |emqx broker实战
spring boot·spring·spring cloud·mybatis