策略模式随笔~

若感行文枯燥,请移步至文末Gitee地址中查看源码自行测试感受策略模式之魅力。

一、策略模式的核心概念

策略模式的定义

定义算法族,封装每个算法,使其可互换。

核心三要素

  • Context:上下文,负责接收客户端请求并委托具体策略对象处理,实现业务逻辑与算法实现的解耦。
  • Strategy:定义接口和规范
  • ConcreteStrategy:具体的实现策略

如果把策略模式想象成一个万能遥控器,遥控器通过不同的控制卡控制不同的设备实现不同的功能;遥控器承担Context角色,作为控制中枢提供统一操作入口;控制卡接口插槽则是对应Strategy,定义标准功能;空调、灯光、音箱控制卡则是具体的实现策略(ConcreteStrategy),各自实现温度调节、亮度调控、音量控制等具体功能。

本质

Java中推荐面向接口编程,而非面向实现,策略模式作为这一原则的典型应用,通过抽象策略接口与具体实现解耦,有新的扩展需求时,只需要增加其实现即可,而无需对源代码进行改动,也符合对新增开放,对修改关闭的原则(开闭原则)。基于这种设计思想,在新增设备类型时(如加湿器控制卡),只需扩展新的策略实现而无需修改遥控器本体,即无需修改原代码,只在原代码的基础上新增。

模式结构解析

将策略模式的结构应用于真实且常见的业务场景如支付场景,如在门诊收费页面,用户可以选择支付宝、微信、银联支付,不同的支付方式交互的方式不同,则需要不同的支付实现策略,那么结构参考下图:

二、解决了什么问题&应用场景

应用场景

在支付实际业务场景中,我们需要使用支持不同的支付方式如:支付宝、微信、银联,每种支付方式调用的接口API、请求参数、返回结果各不相同,有时系统有接入新的支付方式的需求,同时支付相关的业务逻辑比较复杂,每种支付方式的实现代码都会比较长,尤其是聚合了多种支付方式的系统,在维护和开发时成本都更高。

解决了什么问题

策略模式解决了以下痛点:

  1. 代码耦合高 :不同支付方式实现混杂在业务逻辑中,存在大量if-else/switch分支
  2. 扩展成本高:新增支付方式需要修改原有支付逻辑,违反开闭原则
  3. 可维护性差:单个方法可能膨胀至上千行,参数传递混乱(如不同支付方式参数通过Map传递)
  4. 测试便利性: 新增策略时可以直接测试新逻辑,不影响原逻辑

代码示例

使用伪代码展示当业务逻辑复杂时,if、switch、策略模式各自的实现方案。

if-else
java 复制代码
@Slf4j
@Service
public class IfPaymentServiceImpl implements IfPaymentService {
    @Override
    public String pay(String type, BigDecimal amount) {
        if (Constant.PAYConstant.ALI_PAY.equals(type)) {
            return "支付宝支付成功,金额:" + amount;
        } else if (Constant.PAYConstant.WECHAT_PAY.equals(type)) {
            return "微信支付成功,金额:" + amount;
        } else if (Constant.PAYConstant.UNION_PAY.equals(type)) {
            return "银联支付成功,金额:" + amount;
        }
        throw new IllegalArgumentException("无效支付方式");
    }
}
switch-case
java 复制代码
public class SwitchPaymentServiceImpl implements SwitchPaymentService {
    @Override
    public String pay(String type, BigDecimal amount) {

        switch (type) {
            case Constant.PAYConstant.ALI_PAY:
                return "支付宝支付成功,金额:" + amount;
            case Constant.PAYConstant.WECHAT_PAY:
                return "微信支付成功,金额:" + amount;
            case Constant.PAYConstant.UNION_PAY:
                return "银联支付成功,金额:" + amount;
            default:
                throw new IllegalArgumentException("无效支付方式");
        }
    }
}
策略模式

支付方式的策略工厂,类比于使遥控器找到对应的功能的控制卡。

java 复制代码
/**
 * 支付方式的策略工厂
 */
@Slf4j
@Component
public class PaymentStrategyFactory {

    /**
     * 策略池
     */
    private final Map<String, PaymentService> STRATEGY_MAP = new ConcurrentHashMap<>();

    @Resource
    private List<PaymentService> strategies;

    /**
     * Spring启动时注入所有的支付策略
     */
    @PostConstruct
    public void initStrategies() {
        for (PaymentService strategy : strategies) {
            log.info("注入策略:{}", strategy.getClass().getSimpleName());
            String type = strategy.getClass().getSimpleName()
                    .replace("Strategy", "");
            STRATEGY_MAP.put(type, strategy);
        }
    }


    /**
     * 根据上下文获取支付策略
     * @param type 上下文参数
     * @return 支付策略
     */
    public PaymentService getStrategy(String type) {
        PaymentService paymentService = STRATEGY_MAP.get(type);
        return Optional.ofNullable(paymentService)
                .orElseThrow(() -> new IllegalArgumentException("无效支付类型"));
    }

}

类比于遥控器中插槽,定义标准功能。

java 复制代码
public interface PaymentService {
    
    /**
     * 支付接口
     */
    String pay(String type, BigDecimal amount);
}

具体实现策略,指定遥控器可以控制设备的具体功能的视线方式。

java 复制代码
@Slf4j
@Component
public class AlipayStrategy implements PaymentService {
    @Override
    public String pay(String type, BigDecimal amount) {
        try {
            Thread.sleep(2000);
        } catch (Exception e) {
            log.info("异常", e);
        }
        return "支付宝支付成功,金额:" + amount;
    }
}

代码地址

源码

相关推荐
拾光Ծ1 小时前
【Linux系统编程】线程池项目实战与基于策略模式的日志系统
linux·bash·线程池·策略模式·日志
星原望野19 小时前
JAVA:策略模式的实战使用
java·开发语言·策略模式
前端张三20 小时前
从零构建大模型(零)——搭建配置环境
策略模式
j_xxx404_1 天前
Linux 线程日志系统设计:从策略模式、RAII 到 pthread 线程安全与内核写入路径|附源码
linux·运维·服务器·开发语言·c++·人工智能·策略模式
代码小书生4 天前
shutil,一个文件操作的 Python 库!
开发语言·python·策略模式
ting94520004 天前
ModelHub 深度技术解析:macOS 原生菜单栏 LLM 模型管理工具,补齐 Ollama/MLX/LM Studio 生态短板
人工智能·macos·架构·策略模式
张小姐的猫4 天前
【Linux】多线程实战 —— 日志类 | 策略模式
linux·运维·服务器·c++·bash·策略模式
老码观察5 天前
设计模式实战解读(五):策略模式——干掉 if-else 的优雅方案
java·设计模式·策略模式
无聊的老谢6 天前
构建高扩展性的动态指标计算引擎:策略模式与表达式树的实战应用
java·策略模式·计算引擎
IT空门:门主6 天前
Java 设计模式实战:模板方法 + 工厂 + 策略模式重构支付系统
java·设计模式·策略模式