Java 设计模式:策略模式详解
策略模式(Strategy Pattern)是一种行为型设计模式,它定义了一系列算法,将每个算法封装起来,并使它们可以相互替换。策略模式让算法的变化独立于使用算法的客户端,从而提高代码的灵活性和可维护性。本文将介绍策略模式的定义、实现方式及其在 Java 中的应用。
1. 什么是策略模式?
策略模式的核心思想是:将不同的行为或算法抽象为独立的对象,通过上下文动态选择和执行这些策略。它遵循"开闭原则",便于在不修改客户端代码的情况下扩展新策略。
模式结构
- 抽象策略(Strategy):定义算法的接口。
- 具体策略(Concrete Strategy):实现抽象策略,提供具体的算法实现。
- 上下文(Context):持有策略对象的引用,负责调用策略。
2. 策略模式的实现方式
以下是一个示例:模拟一个支付系统,支持多种支付策略(如微信支付、支付宝支付)。
2.1 定义抽象策略接口
java
public interface PaymentStrategy {
void pay(double amount); // 支付方法
}
2.2 实现具体策略
java
public class WeChatPayment implements PaymentStrategy {
@Override
public void pay(double amount) {
System.out.println("使用微信支付 " + amount + " 元");
}
}
public class AlipayPayment implements PaymentStrategy {
@Override
public void pay(double amount) {
System.out.println("使用支付宝支付 " + amount + " 元");
}
}
public class CreditCardPayment implements PaymentStrategy {
@Override
public void pay(double amount) {
System.out.println("使用信用卡支付 " + amount + " 元");
}
}
2.3 定义上下文
java
public class PaymentContext {
private PaymentStrategy paymentStrategy;
// 通过构造方法或 setter 注入策略
public PaymentContext(PaymentStrategy paymentStrategy) {
this.paymentStrategy = paymentStrategy;
}
public void setPaymentStrategy(PaymentStrategy paymentStrategy) {
this.paymentStrategy = paymentStrategy;
}
// 执行支付
public void executePayment(double amount) {
paymentStrategy.pay(amount);
}
}
2.4 客户端使用
java
public class Client {
public static void main(String[] args) {
// 创建上下文并选择策略
PaymentContext context = new PaymentContext(new WeChatPayment());
context.executePayment(100.0);
// 动态切换策略
context.setPaymentStrategy(new AlipayPayment());
context.executePayment(50.0);
// 再切换到信用卡支付
context.setPaymentStrategy(new CreditCardPayment());
context.executePayment(200.0);
}
}
输出结果
使用微信支付 100.0 元
使用支付宝支付 50.0 元
使用信用卡支付 200.0 元
3. 使用 Lambda 表达式优化
在 Java 8+ 中,可以利用函数式编程简化策略模式,去掉显式的策略类:
java
import java.util.function.Consumer;
public class PaymentContext {
private Consumer<Double> paymentStrategy;
public PaymentContext(Consumer<Double> paymentStrategy) {
this.paymentStrategy = paymentStrategy;
}
public void setPaymentStrategy(Consumer<Double> paymentStrategy) {
this.paymentStrategy = paymentStrategy;
}
public void executePayment(double amount) {
paymentStrategy.accept(amount);
}
public static void main(String[] args) {
PaymentContext context = new PaymentContext(amount -> System.out.println("使用微信支付 " + amount + " 元"));
context.executePayment(100.0);
context.setPaymentStrategy(amount -> System.out.println("使用支付宝支付 " + amount + " 元"));
context.executePayment(50.0);
}
}
这种方式更简洁,但适用于策略逻辑较简单的场景。
4. 策略模式的优缺点
优点
- 算法可替换:运行时动态切换策略,灵活性高。
- 符合开闭原则:新增策略无需修改上下文代码。
- 解耦算法与客户端:客户端无需了解具体实现细节。
缺点
- 类数量增加:每种策略都需要一个类,复杂场景下可能导致类膨胀。
- 客户端需选择策略:客户端必须知道所有策略并决定使用哪一个。
5. 实际应用场景
- 排序算法 :如 Java 的
Collections.sort()
,通过Comparator
动态选择排序策略。 - 支付系统:本文示例中的多支付方式切换。
- 游戏AI:根据场景选择不同的行为策略(如进攻、防守)。
示例:Java 中的 Comparator
java
List<String> list = Arrays.asList("apple", "banana", "cherry");
Collections.sort(list, (a, b) -> a.length() - b.length()); // 按长度排序
这里的 Comparator
就是一种策略模式的应用。
6. 与工厂模式的区别
- 策略模式:关注行为或算法的动态选择,运行时切换。
- 工厂模式:关注对象的创建,生成后对象行为通常固定。
7. 总结
策略模式通过将算法封装为独立的对象,实现了行为的高内聚和低耦合。它特别适合需要动态切换逻辑的场景,如支付方式、数据处理规则等。在 Java 中,结合接口或 Lambda 表达式,可以让策略模式更简洁高效。掌握这一模式,能显著提升代码的灵活性和可扩展性。
希望这篇博文能帮助你理解策略模式的精髓!如果有其他设计模式相关问题,欢迎留言讨论。