泛型加持的策略模式:打造高扩展的通用策略工具类

news2025/5/13 19:46:25

一、传统策略模式的痛点与突破

1.1 传统策略实现回顾

// 传统支付策略接口
public interface PaymentStrategy {
    void pay(BigDecimal amount);
}

// 具体策略实现
public class AlipayStrategy implements PaymentStrategy {
    public void pay(BigDecimal amount) { /* 支付宝支付逻辑 */ }
}

// 策略上下文
public class PaymentContext {
    private PaymentStrategy strategy;
    
    public void setStrategy(PaymentStrategy strategy) {
        this.strategy = strategy;
    }
    
    public void executePayment(BigDecimal amount) {
        strategy.pay(amount);
    }
}

存在问题
❌ 策略类型固定,无法通用化
❌ 新增策略需修改上下文类
❌ 无法动态管理策略集合


二、泛型化策略工具类设计

2.1 核心接口定义

/**
 * 通用策略接口
 * @param <T> 策略参数类型
 * @param <R> 返回结果类型
 */
public interface GenericStrategy<T, R> {
    /**
     * 是否支持当前策略类型
     */
    boolean support(String strategyType);
    
    /**
     * 执行策略
     */
    R apply(T param);
}

2.2 策略上下文工具类

public class StrategyContext<T, R> {
    private final Map<String, GenericStrategy<T, R>> strategyMap = new ConcurrentHashMap<>();
    
    /**
     * 注册策略
     */
    public void registerStrategy(String strategyType, GenericStrategy<T, R> strategy) {
        strategyMap.put(strategyType, strategy);
    }
    
    /**
     * 执行策略
     */
    public R execute(String strategyType, T param) {
        GenericStrategy<T, R> strategy = Optional.ofNullable(strategyMap.get(strategyType))
            .orElseThrow(() -> new IllegalArgumentException("未找到策略: " + strategyType));
        return strategy.apply(param);
    }
    
    /**
     * 批量执行策略
     */
    public List<R> executeAll(T param) {
        return strategyMap.values().stream()
            .map(s -> s.apply(param))
            .collect(Collectors.toList());
    }
}

三、Spring集成与自动装配

3.1 自动注册策略实现

@Configuration
public class StrategyAutoConfiguration {
    
    /**
     * 自动发现所有策略Bean并注册
     */
    @Bean
    public <T, R> StrategyContext<T, R> strategyContext(
        List<GenericStrategy<T, R>> strategies) {
        StrategyContext<T, R> context = new StrategyContext<>();
        strategies.forEach(strategy -> 
            context.registerStrategy(
                strategy.getClass().getAnnotation(StrategyType.class).value(),
                strategy
            )
        );
        return context;
    }
}

/**
 * 策略类型注解
 */
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public @interface StrategyType {
    String value();
}

3.2 策略实现示例

@StrategyType("alipay")
@Component
public class AlipayStrategy implements GenericStrategy<PaymentRequest, PaymentResult> {
    @Override
    public boolean support(String strategyType) {
        return "alipay".equals(strategyType);
    }
    
    @Override
    public PaymentResult apply(PaymentRequest request) {
        // 支付宝支付具体实现
    }
}

四、企业级应用案例

4.1 支付策略路由

@RestController
@RequestMapping("/payment")
public class PaymentController {
    @Autowired
    private StrategyContext<PaymentRequest, PaymentResult> paymentContext;
    
    @PostMapping("/{type}")
    public PaymentResult pay(@PathVariable String type, @RequestBody PaymentRequest request) {
        return paymentContext.execute(type, request);
    }
}

4.2 动态折扣计算

public enum DiscountType {
    NEW_USER, 
    FESTIVAL, 
    VIP_LEVEL
}

public class DiscountStrategy implements GenericStrategy<DiscountType, BigDecimal> {
    private static final Map<DiscountType, BigDecimal> DISCOUNT_MAP = Map.of(
        DiscountType.NEW_USER, new BigDecimal("0.9"),
        DiscountType.FESTIVAL, new BigDecimal("0.8"),
        DiscountType.VIP_LEVEL, new BigDecimal("0.7")
    );
    
    @Override
    public boolean support(String strategyType) {
        return Arrays.stream(DiscountType.values())
            .anyMatch(e -> e.name().equals(strategyType));
    }
    
    @Override
    public BigDecimal apply(DiscountType type) {
        return DISCOUNT_MAP.get(type);
    }
}

五、高级功能扩展

5.1 策略优先级控制

public class PriorityStrategyContext<T, R> extends StrategyContext<T, R> {
    private final PriorityQueue<GenericStrategy<T, R>> priorityQueue = 
        new PriorityQueue<>(Comparator.comparingInt(this::getPriority));
    
    private int getPriority(GenericStrategy<T, R> strategy) {
        return strategy.getClass().isAnnotationPresent(StrategyPriority.class) ?
            strategy.getClass().getAnnotation(StrategyPriority.class).value() : 0;
    }
    
    @Override
    public void registerStrategy(String type, GenericStrategy<T, R> strategy) {
        super.registerStrategy(type, strategy);
        priorityQueue.offer(strategy);
    }
    
    public R executeFirst(T param) {
        return priorityQueue.peek().apply(param);
    }
}

5.2 策略执行监控

public class MonitoredStrategyContext<T, R> extends StrategyContext<T, R> {
    private final MeterRegistry meterRegistry;
    
    @Override
    public R execute(String strategyType, T param) {
        Timer.Sample sample = Timer.start(meterRegistry);
        try {
            R result = super.execute(strategyType, param);
            sample.stop(meterRegistry.timer("strategy.execute.time", "type", strategyType));
            return result;
        } catch (Exception e) {
            meterRegistry.counter("strategy.error", "type", strategyType).increment();
            throw e;
        }
    }
}

六、最佳实践总结

  1. 合理定义策略边界:每个策略应聚焦单一职责

  2. 统一异常处理:定义策略执行异常体系

  3. 版本控制策略:支持多版本策略共存

  4. 动态配置支持:结合配置中心实现热更新

  5. 性能优化:缓存高频使用策略

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2374893.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【优选算法 | 链表】链表操作技巧:常见算法

算法相关知识点可以通过点击以下链接进行学习一起加油&#xff01;双指针滑动窗口二分查找前缀和位运算模拟 链表是一种灵活的数据结构&#xff0c;广泛用于需要频繁插入和删除的场景。掌握链表的常见操作技巧&#xff0c;如插入、删除、翻转和合并等&#xff0c;能帮助开发者更…

w~大模型~合集30

我自己的原文哦~ https://blog.51cto.com/whaosoft/13284996 #VideoMamba 视频理解因大量时空冗余和复杂时空依赖&#xff0c;同时克服两个问题难度巨大&#xff0c;CNN 和 Transformer 及 Uniformer 都难以胜任&#xff0c;Mamba 是个好思路&#xff0c;让我们看看本文是…

PBR材质-Unity/Blender/UE

目录 前言&#xff1a; 一、Unity&#xff1a; 二、Blender&#xff1a; 三、UE&#xff1a; 四、全家福&#xff1a; 五、后记&#xff1a; 前言&#xff1a; PBR流程作为表达物理效果的经典方式&#xff0c;很值得一学。纹理贴图使用的是上一期的Textures | cgbookcas…

websocketpp 安装及使用

介绍 WebSocket 是从 HTML5 开始支持的一种网页端和服务端保持长连接的消息推送机制。 传统的 web 程序都是属于 "一问一答" 的形式&#xff0c;即客户端给服务器发送了一个 HTTP 请求&#xff0c;服务器给客户端返回一个 HTTP 响应。这种情况下服务器是属于被动…

第8章-2 查询执行的基础

上一篇&#xff1a;《第8章-1 查询性能优化-优化数据访问》&#xff0c;接着来了解查询执行的过程&#xff0c;这个对sql执行有个更直观的了解。 查询执行的基础 当希望MySQL能够以更高的性能运行查询时&#xff0c;最好的办法就是弄清楚MySQL是如何优化和执行查询的。一旦理解…

java面试OOM汇总

在正式 Minor GC 前&#xff0c;JVM 会先检查新生代中对象&#xff0c;是比老年代中剩余空间大还是小。假如 Minor GC之后 Survivor 区放不下剩余对象&#xff0c;这些对象就要进入老年代 老年代剩余空间大于新生代中的对象大小&#xff0c;那就直接 Minor GC&#xff0c; GC 完…

react-diff-viewer 如何实现语法高亮

前言 react-diff-viewer 是一个很好的 diff 展示库&#xff0c;但是也有一些坑点和不完善的地方&#xff0c;本文旨在描述如何在这个库中实现自定义语法高亮。 Syntax highlighting is a bit tricky when combined with diff. Here, React Diff Viewer provides a simple rend…

自定义prometheus exporter实现监控阿里云RDS

# 自定义 Prometheus Exporter 实现多 RDS 数据采集## 背景1. Prometheus 官网提供的 MySQL Exporter 对于 MySQL 实例只能一个进程监控一个实例&#xff0c;数据库实例很多的情况下&#xff0c;不方便管理。 2. 内部有定制化监控需求&#xff0c;RDS 默认无法实现&#xff0c;…

【计算机网络】--tcp三次握手

文章目录 示意图&#xff1a;抓包结果&#xff1a;第一次握手&#xff08;Client → Server&#xff09;第二次握手&#xff08;Server → Client&#xff09;第三次握手&#xff08;Client → Server&#xff09;为什么是三次握手 不是两次或者四次 示意图&#xff1a; 抓包结…

UI-TARS: 基于视觉语言模型的多模式代理

GitHub&#xff1a;https://github.com/bytedance/UI-TARS 更多AI开源软件&#xff1a;发现分享好用的AI工具、AI开源软件、AI模型、AI变现 - 小众AI 基于视觉语言模型&#xff08;Vision-Language Model&#xff09;的 GUI 代理应用&#xff0c;允许用户通过自然语言控制电脑操…

Spark SQL 运行架构详解(专业解释+番茄炒蛋例子解读)

1. 整体架构概览 Spark SQL的运行过程可以想象成一个"SQL查询的加工流水线"&#xff0c;从原始SQL语句开始&#xff0c;经过多个阶段的处理和优化&#xff0c;最终变成分布式计算任务执行。主要流程如下&#xff1a; SQL Query → 解析 → 逻辑计划 → 优化 → 物理…

【计算机网络】网络IP层

&#x1f4da; 博主的专栏 &#x1f427; Linux | &#x1f5a5;️ C | &#x1f4ca; 数据结构 | &#x1f4a1;C 算法 | &#x1f152; C 语言 | &#x1f310; 计算机网络 上篇文章&#xff1a;传输层协议TCP 下篇文章&#xff1a;数据链路层 文章摘要&#xff1…

一天学会Maven

一、Maven简介和快速入门 1.1 Maven介绍 Maven 是一款为 Java 项目构建管理、依赖管理的工具&#xff08;软件&#xff09;&#xff0c;使用 Maven 可以自动化构建、测试、打包和发布项目&#xff0c;大大提高了开发效率和质量。 总结&#xff1a;Maven就是一个软件&#xf…

变量函数实战:高保真APP原型“发票页面”动态交互教程

变量函数是高保真交互原型设计中常见的高级交互功能&#xff0c;能够避免重复复制与手动修改页面元素和逻辑标注&#xff0c;让演示更有真实体验感。本文分享一个高保真APP交互原型页面的实操案例&#xff0c;结合原型设计工具中的变量函数与逻辑判断功能&#xff0c;手把手教你…

Spring Boot 3 + Undertow 服务器优化配置

优化背景 当你的application需要支持瞬时高并发的时候&#xff0c;tomcat已经不在是最优的选择&#xff0c;我们可以改为Undertow&#xff0c;并对其进行优化。 Undertow 是一个轻量级的、高性能的Java Web 服务器&#xff0c;由JBoss 开发并开源。它是基于非阻塞&#xff08;…

7系列 之 OSERDESE2

背景 《ug471_7Series_SelectIO.pdf》介绍了Xilinx 7 系列 SelectIO 的输入/输出特性及逻辑资源的相关内容。 第 1 章《SelectIO Resources》介绍了输出驱动器和输入接收器的电气特性&#xff0c;并通过大量实例解析了各类标准接口的实现。 第 2 章《SelectIO Logic Resource…

vue3+flask+sqlite前后端项目实战

基础环境安装 pycharm 下载地址&#xff1a; https://www.jetbrains.com/zh-cn/pycharm/download/?sectionwindows vscode 下载地址 https://code.visualstudio.com/docs/?dvwin64user python 下载地址 https://www.python.org/downloads/windows/ Node.js&#xff08;含npm…

Java 线程的堆栈跟踪信息

Java 线程的堆栈跟踪信息&#xff0c;展示了线程的当前状态和执行位置。以下是详细解释&#xff1a; 线程基本信息 "Thread-0" #16 prio5 os_prio0 cpu0.00ms elapsed16.29s tid0x00000243105a4130 nid0x5384 waiting on condition [0x0000007687ffe000]线程名称…

【计算机视觉】OpenCV实战项目:Long-Exposure:基于深度学习的长时间曝光合成技术

Long-Exposure&#xff1a;基于深度学习的长时间曝光合成技术 项目概述与技术背景项目核心功能技术原理 环境配置与安装硬件要求建议详细安装步骤可选组件安装 实战应用指南1. 基础使用&#xff1a;视频转长曝光2. 高级模式&#xff1a;自定义光轨合成3. 批量处理模式 技术实现…

传输层协议UDP和TCP

传输层协议UDP和TCP 1、UDP2、TCP2.1、TCP协议段格式2.2、确认应答(ACK)机制2.3、超时重传机制2.4、连接管理机制2.5、理解CLOSE_WAIT状态2.6、理解TIME_WAIT状态2.7、流量控制2.8、滑动窗口2.9、拥塞控制2.10、延迟应答2.11、捎带应答2.12、面向字节流2.13、粘包问题2.14、TCP…