设计模式:策略模式 - 消除复杂条件判断的利器

一、什么是策略模式?

策略模式(Strategy Pattern)是一种行为型设计模式,它将一组算法或业务逻辑封装为独立的策略类,使这些策略可以互换使用,并通过上下文类动态选择合适的策略。

核心思想

• 将不同的行为或算法独立封装为策略类,客户端无需关注内部实现逻辑。

• 遵循开闭原则(OCP),新增策略时无需修改已有代码,避免复杂的if-else判断逻辑。

策略模式的关键结构

1.策略接口(Strategy)

定义一组算法的通用接口。

2.具体策略(Concrete Strategy)

每个具体策略实现不同的算法。

3上下文类(Context)

上下文类持有策略接口的引用,用于调用具体策略。

二、策略模式的实际案例

场景:订单支付系统(支持支付宝、微信和银联支付)。

直接实现(未使用策略模式):

java 复制代码
public class PaymentService {
    public void pay(String paymentType, double amount) {
       // 支付宝支付
        if ("ALIPAY".equals(paymentType)) {
            System.out.println("Using Alipay to pay: " + amount);
       // 微信支付
        } else if ("WECHAT".equals(paymentType)) {
            System.out.println("Using WeChat Pay to pay: " + amount);
       // 银联支付 
        } else if ("UNIONPAY".equals(paymentType)) {
            System.out.println("Using UnionPay to pay: " + amount);
        } else {
            System.out.println("Unsupported payment type!");
        }
    }
}

问题分析

1.违反开闭原则:每新增一种支付方式,都需要修改pay()方法,代码难以维护。

2.可读性和扩展性差:复杂条件判断导致代码臃肿,增加阅读和测试成本。

3.高耦合性:支付逻辑直接耦合在调用代码中,难以重用和扩展。

使用策略模式实现

1.定义支付策略接口

策略模式的第一步是定义一个接口,抽象出所有支付方式的共同行为。

java 复制代码
/**
 * 支付策略接口,所有支付方式必须实现该接口。
 */
public interface PaymentStrategy {
    /**
     * 执行支付操作
     * @param amount 支付金额
     */
    void pay(double amount);
}

2.实现具体的支付策略类

每个支付方式对应一个实现类,独立封装具体的支付逻辑。

java 复制代码
/**
 * 支付宝支付策略
 */
public class AlipayStrategy implements PaymentStrategy {
    @Override
    public void pay(double amount) {
        System.out.println("使用支付宝支付了 " + amount + " 元");
    }
}

/**
 * 微信支付策略
 */
public class WeChatPayStrategy implements PaymentStrategy {
    @Override
    public void pay(double amount) {
        System.out.println("使用微信支付了 " + amount + " 元");
    }
}

/**
 * 银联支付策略
 */
public class UnionPayStrategy implements PaymentStrategy {
    @Override
    public void pay(double amount) {
        System.out.println("使用银联支付了 " + amount + " 元");
    }
}

3.定义支付上下文类

上下文类负责持有具体的策略对象,并在需要时调用对应的支付逻辑。

java 复制代码
/**
 * 支付上下文类,用于管理支付策略
 */
public class PaymentContext {
    // 策略对象
    private PaymentStrategy paymentStrategy;

    /**
     * 构造方法,初始化支付策略
     */
    public PaymentContext(PaymentStrategy paymentStrategy) {
        this.paymentStrategy = paymentStrategy;
    }

    /**
     * 执行支付操作
     * @param amount 支付金额
     */
    public void executePayment(double amount) {
        paymentStrategy.pay(amount);
    }
}

4.客户端代码:选择支付方式并支付

客户端通过选择不同的策略,实现不同的支付方式。

java 复制代码
/**
 * 客户端测试代码
 */
public class Client {
    public static void main(String[] args) {
        double amount = 200.0; // 支付金额

        // 使用支付宝支付
        PaymentContext context = new PaymentContext(new AlipayStrategy());
        context.executePayment(amount);

        // 使用微信支付
        context = new PaymentContext(new WeChatPayStrategy());
        context.executePayment(amount);

        // 使用银联支付
        context = new PaymentContext(new UnionPayStrategy());
        context.executePayment(amount);
    }
}

运行结果:

bash 复制代码
使用支付宝支付了 200.0 元
使用微信支付了 200.0 元
使用银联支付了 200.0 元

代码结构说明

1.策略接口PaymentStrategy

定义支付方法pay(),所有支付类须实现它。

2.具体策略类

AlipayStrategy:实现支付宝支付逻辑。

WeChatPayStrategy:微信支付逻辑。

UnionPayStrategy:实现银联支付逻辑。

3.上下文类PaymentContext

维护一个策略对象,客户端可以动态选择不同的支付策略。

4.客户端

通过创建不同的支付策略对象,实现灵活的支付功能。

三、策略模式的价值

1.简化主逻辑,消除复杂条件判断

策略模式将复杂的if-else或switch-case语句分解为独立的策略类,使主逻辑更专注于调用流程(上下文),代码清晰且易维护。

2.便于扩展,符合开闭原则

新增功能(如支付方式)时,只需新增策略类,无需修改现有代码,既减少对稳定模块的干扰,也降低扩展成本。

3.提升复用性

策略类通过模块化设计,将具体逻辑与选择逻辑分离,可直接复用于其他系统。

四、适用场景

1.动态行为选择

系统需要在运行时根据不同条件选择不同的行为或算法,例如支付方式切换、促销规则变化、日志格式化样式调整等。

2.简化条件分支

当代码中存在大量if-else或switch-case时,且未来可能增加判断分支时,可通过策略模式优化为独立的策略类,提升可维护性。

3.高扩展性需求

系统需要频繁新增功能,但不希望频繁修改现有代码,策略模式符合开闭原则(OCP)。

4.测试驱动开发场景

需要对不同行为进行独立验证时,策略模式将这些行为解耦,便于单独测试。

五、总结

策略模式通过将行为或算法封装为独立类,结合上下文动态选择策略,提升了系统的灵活性、扩展性与可维护性。

核心价值

• 开发上,简化主逻辑,消除复杂条件判断,增强扩展性与复用性。

• 测试上,降低模块间耦合性,简化单元测试,降低回归测试成本。

1.策略类过多可能导致类数量膨胀,应合理设计。

2.在简单场景下,策略模式可能显得"过度设计",需权衡实际需求。

相关推荐
晨米酱2 小时前
JavaScript 中"对象即函数"设计模式
前端·设计模式
数据智能老司机7 小时前
精通 Python 设计模式——分布式系统模式
python·设计模式·架构
数据智能老司机8 小时前
精通 Python 设计模式——并发与异步模式
python·设计模式·编程语言
数据智能老司机8 小时前
精通 Python 设计模式——测试模式
python·设计模式·架构
数据智能老司机8 小时前
精通 Python 设计模式——性能模式
python·设计模式·架构
使一颗心免于哀伤8 小时前
《设计模式之禅》笔记摘录 - 21.状态模式
笔记·设计模式
数据智能老司机1 天前
精通 Python 设计模式——创建型设计模式
python·设计模式·架构
数据智能老司机1 天前
精通 Python 设计模式——SOLID 原则
python·设计模式·架构
烛阴1 天前
【TS 设计模式完全指南】懒加载、缓存与权限控制:代理模式在 TypeScript 中的三大妙用
javascript·设计模式·typescript
李广坤1 天前
工厂模式
设计模式