策略模式(Strategy Pattern)是一种行为型设计模式,旨在定义一系列算法,将每个算法封装起来,并使它们可以互相替换,从而使得算法的变化不会影响使用算法的客户端。策略模式的主要结构包括策略接口、具体策略类和上下文类,通过将算法的选择与使用分离,实现了代码的可维护性和灵活性。
更多设计模式请参考:Java 中的 23 种设计模式详解
在软件开发中,经常遇到需要在运行时动态选择一种算法的情况。例如,排序算法、支付方式、文件压缩等场景都可能需要在不同条件下选择不同的算法实现。如果在客户端代码中硬编码这些算法的选择逻辑,会导致代码难以维护和扩展。策略模式通过将算法的选择和实现分离,使得算法可以独立变化,客户端代码可以更简洁和灵活。
策略模式包含以下几部分:

以下是一个使用策略模式的Java示例,该示例演示了如何选择不同的策略来执行操作:
// 定义策略接口 public interface Strategy { void execute(); } // 具体策略A public class ConcreteStrategyA implements Strategy { @Override public void execute() { System.out.println("执行策略A"); } } // 具体策略B public class ConcreteStrategyB implements Strategy { @Override public void execute() { System.out.println("执行策略B"); } } // 上下文类 public class Context { private Strategy strategy; // 设置策略 public void setStrategy(Strategy strategy) { this.strategy = strategy; } // 执行策略 public void executeStrategy() { if (strategy == null) { throw new IllegalStateException("Strategy未设置"); } strategy.execute(); } } public class StrategyPatternDemo { public static void main(String[] args) { Context context = new Context(); // 使用策略A context.setStrategy(new ConcreteStrategyA()); context.executeStrategy(); // 输出: 执行策略A // 使用策略B context.setStrategy(new ConcreteStrategyB()); context.executeStrategy(); // 输出: 执行策略B } } 策略模式适用于以下场景:
策略模式可以与其他设计模式结合使用,以增强其功能。例如:
在某些情况下,策略的初始化可能比较耗时,可以使用延迟初始化(Lazy Initialization)来提高性能:
public class Context { private Strategy strategy; public void setStrategy(Strategy strategy) { this.strategy = strategy; } public void executeStrategy() { if (strategy == null) { // 延迟初始化 strategy = new ConcreteStrategyA(); } strategy.execute(); } } 为了避免频繁修改代码,可以通过反射动态加载策略:
public class Context { private Strategy strategy; public void setStrategy(String strategyClassName) throws Exception { this.strategy = (Strategy) Class.forName(strategyClassName).getDeclaredConstructor().newInstance(); } public void executeStrategy() { strategy.execute(); } } 将策略的配置放在配置文件中,便于管理和维护:
# strategy.properties strategy=ConcreteStrategyA import java.io.InputStream; import java.util.Properties; public class StrategyLoader { public static Strategy loadStrategy() throws Exception { Properties properties = new Properties(); try (InputStream input = StrategyLoader.class.getResourceAsStream("/strategy.properties")) { properties.load(input); } String strategyClassName = properties.getProperty("strategy"); return (Strategy) Class.forName(strategyClassName).getDeclaredConstructor().newInstance(); } } 结合依赖注入框架(如Spring),可以更加灵活地管理策略的实例:
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; @Component public class Context { private final Strategy strategy; @Autowired public Context(Strategy strategy) { this.strategy = strategy; } public void executeStrategy() { strategy.execute(); } } 
在一个支付系统中,可能有多种支付方式,如信用卡支付、支付宝支付、微信支付等。通过策略模式,可以根据用户选择的支付方式动态切换支付策略。
public interface PaymentStrategy { void pay(double amount); } // 信用卡支付策略 public class CreditCardPaymentStrategy implements PaymentStrategy { @Override public void pay(double amount) { System.out.println("使用信用卡支付:" + amount + "元"); } } // 支付宝支付策略 public class AliPayPaymentStrategy implements PaymentStrategy { @Override public void pay(double amount) { System.out.println("使用支付宝支付:" + amount + "元"); } } // 微信支付策略 public class WeChatPaymentStrategy implements PaymentStrategy { @Override public void pay(double amount) { System.out.println("使用微信支付:" + amount + "元"); } } public class PaymentContext { private PaymentStrategy paymentStrategy; // 设置支付策略 public void setPaymentStrategy(PaymentStrategy paymentStrategy) { this.paymentStrategy = paymentStrategy; } // 执行支付 public void pay(double amount) { if (paymentStrategy == null) { throw new IllegalStateException("PaymentStrategy未设置"); } paymentStrategy.pay(amount); } } 为了更加优雅地创建支付策略,可以使用工厂模式:
public class PaymentStrategyFactory { public static PaymentStrategy getPaymentStrategy(String type) { switch (type) { case "CreditCard": return new CreditCardPaymentStrategy(); case "AliPay": return new AliPayPaymentStrategy(); case "WeChat": return new WeChatPaymentStrategy(); default: throw new IllegalArgumentException("未知的支付类型: " + type); } } } public class PaymentDemo { public static void main(String[] args) { PaymentContext context = new PaymentContext(); // 从外部获取支付类型,例如通过用户输入或配置文件 String paymentType = "CreditCard"; // 这里可以根据实际情况更改 // 使用工厂创建支付策略 PaymentStrategy paymentStrategy = PaymentStrategyFactory.getPaymentStrategy(paymentType); // 设置支付策略 context.setPaymentStrategy(paymentStrategy); // 执行支付 context.pay(100.0); // 输出: 使用信用卡支付:100.0元 // 更改支付策略 paymentType = "AliPay"; paymentStrategy = PaymentStrategyFactory.getPaymentStrategy(paymentType); context.setPaymentStrategy(paymentStrategy); context.pay(200.0); // 输出: 使用支付宝支付:200.0元 // 更改支付策略 paymentType = "WeChat"; paymentStrategy = PaymentStrategyFactory.getPaymentStrategy(paymentType); context.setPaymentStrategy(paymentStrategy); context.pay(300.0); // 输出: 使用微信支付:300.0元 } } 通过策略模式和工厂模式的结合,可以实现一个灵活、可扩展且易于维护的支付系统。在实际开发中,进一步结合依赖注入框架(如Spring)来管理策略对象,可以提升代码的可测试性和可扩展性。