策略模式

策略(Strategy)模式属于行为型模式的一种。

策略模式的核心思想是定义一系列算法,将每个算法封装起来,并使它们可以互换。策略模式让算法独立于使用它的客户而变化,从而实现了算法族的独立扩展和替换。

策略模式指在一个方法中,某些关键步骤的算法依赖调用方传入的策略,传入不同的策略,即可获得不同的结果,大大增强了系统的灵活性。

策略模式的核心思想是在一个计算方法中把容易变化的算法抽出来作为"策略"参数传进去,如果新增策略的话,则不必修改原有逻辑。

策略模式适用于以下场景:

  • 当系统中存在多个相似的算法或行为,并且需要在运行时根据条件进行选择时。
  • 当需要在不同的业务场景下灵活地替换算法,而不影响系统的整体结构时。
  • 当多个类仅在算法或行为上有所不同,使用策略模式可以将它们的变化部分提取出来,避免代码重复。

策略模式通常有以下组成部分:

  • 策略接口(Strategy):定义一个公共接口,声明所有具体策略类必须实现的方法。
  • 具体策略类(ConcreteStrategy):实现策略接口,封装具体的算法或业务逻辑。每个具体策略代表一种算法实现。
  • 上下文(Context):维护一个策略对象的引用,客户端通过上下文来调用策略对象的方法,从而实现行为的切换。

我们模拟实现一个支付方式的选择功能,不同的支付方式(如信用卡支付和PayPal支付)封装为不同的策略。

1、策略接口:定义支付算法

java 复制代码
// 策略接口:定义支付算法
public interface PaymentStrategy {
    void pay(int amount);
}

2、具体策略类

java 复制代码
// 具体策略类1:信用卡支付
public class CreditCardPaymentStrategy implements PaymentStrategy {
    private String cardNumber;
    
    public CreditCardPaymentStrategy(String cardNumber) {
        this.cardNumber = cardNumber;
    }
    
    @Override
    public void pay(int amount) {
        System.out.println("Using Credit Card (" + cardNumber + ") to pay " + amount + " dollars.");
    }
}

// 具体策略类2:PayPal支付
public class PaypalPaymentStrategy implements PaymentStrategy {
    private String email;
    
    public PaypalPaymentStrategy(String email) {
        this.email = email;
    }
    
    @Override
    public void pay(int amount) {
        System.out.println("Using PayPal (" + email + ") to pay " + amount + " dollars.");
    }
}

3、上下文类:购物车(或支付环境)

java 复制代码
// 上下文类:购物车(或支付环境)
public class ShoppingCart {
    // 持有一个策略对象
    private PaymentStrategy paymentStrategy;
    
    // 设置策略(可在运行时动态切换)
    public void setPaymentStrategy(PaymentStrategy paymentStrategy) {
        this.paymentStrategy = paymentStrategy;
    }
    
    // 结账时调用支付策略
    public void checkout(int amount) {
        if (paymentStrategy == null) {
            throw new IllegalStateException("Payment strategy not set.");
        }
        paymentStrategy.pay(amount);
    }
}

4、客户端

java 复制代码
// 客户端代码
public class StrategyPatternDemo {
    public static void main(String[] args) {
        ShoppingCart cart = new ShoppingCart();
        
        // 使用信用卡支付
        cart.setPaymentStrategy(new CreditCardPaymentStrategy("1234-5678-9012-3456"));
        cart.checkout(150);
        
        // 切换为PayPal支付
        cart.setPaymentStrategy(new PaypalPaymentStrategy("user@example.com"));
        cart.checkout(250);
    }
}

策略模式的优缺点

优点:

  • 灵活性高:策略模式允许在运行时更换算法,实现了算法的动态切换。
  • 封装变化:将变化的算法封装在独立的策略类中,遵循了单一职责原则和开闭原则。
  • 消除条件判断:避免了大量的条件判断语句,使代码结构更加清晰。

缺点:

  • 类的数量增加:每个策略都需要一个单独的类,当算法较多时,可能会导致类的数量增加。
  • 客户端必须知道所有策略:有时客户端需要了解不同策略的细节,并在合适的时机选择合适的策略,这可能会增加系统的复杂性。

装饰模式 可以更改对象的外表,策略模式则能够改变其本质。

策略模式通过将算法封装在独立的策略类中,并在运行时动态选择算法,提供了一种灵活、可扩展的解决方案,能够有效地消除冗长的条件语句,提高系统的可维护性和扩展性。熟练掌握策略模式不仅可以优化代码结构,还可以应对复杂业务场景下的算法替换问题。

人生一切所谓的苦难,都是比较而言。-- 烟沙九洲

相关推荐
专注API从业者15 分钟前
Open Claw 京东商品监控选品实战:一键抓取、实时监控、高效选品
java·服务器·数据库
摇滚侠32 分钟前
DBeaver 导入数据库 导入 SQL 文件 MySQL 备份恢复
java·数据库·mysql
keep one's resolveY1 小时前
SpringBoot实现重试机制的四种方案
java·spring boot·后端
天空属于哈夫克32 小时前
企业微信API常见的错误和解决方案
java·数据库·企业微信
摇滚侠2 小时前
VMvare 虚拟机 Oracle19c 安装步骤,远程连接 Oracle19c,百度网盘安装包
java·oracle
梁萌2 小时前
idea报错找不到XX包的解决方法
java·intellij-idea·启动报错·缺少包
Agent产品评测局2 小时前
生产排期与MES/ERP系统打通,实操方法详解 —— 2026企业级智能体自动化选型与实战指南
java·运维·人工智能·ai·chatgpt·自动化
阿丰资源3 小时前
基于Spring Boot的电影城管理系统(直接运行)
java·spring boot·后端
呱牛do it3 小时前
企业级门户网站设计与实现:基于SpringBoot + Vue3的全栈解决方案(Day 8)
java
消失的旧时光-19434 小时前
Spring Boot 工程化进阶:统一返回 + 全局异常 + AOP 通用工具包
java·spring boot·后端·aop·自定义注解