策略模式示例
策略模式的本质是定义一系列算法,将每一个算法封装起来,并使它们可以相互替换。策略模式让算法的变化独立于使用算法的客户。笔者将通过一个 Java 示例详细说明如何实现策略模式,并探讨其最佳实践,以提高代码的灵活性和可维护性。
策略模式简介
策略模式通过将不同的算法封装成独立的策略类,使得客户端可以根据需要选择和切换不同的策略,而无需修改客户端代码。这种模式特别适用于需要在运行时动态切换算法或行为的场景。
核心组成
策略模式主要由以下三个部分组成:
策略接口:所有策略类必须遵循的接口,定义了解决问题的策略或方法。
策略实现:具体实现策略接口的类,提供了解决问题的具体方法或算法。
上下文:维护一个对策略对象的引用,当需要解决问题时,上下文会使用这个策略对象。上下文可以在运行时更改策略对象,以动态地改变解决问题的方法。
策略接口
首先,笔者定义了一个策略接口 PaymentStrategy,该接口声明了一个 pay 方法,用于执行具体的支付操作。
public interface PaymentStrategy {
    void pay(double amount);
}
策略实现
接下来,笔者创建了多个实现 PaymentStrategy 接口的类,每个类代表一种具体的支付方式。
// 使用信用卡支付的策略实现
public class CreditCardPayment implements PaymentStrategy {
    private String cardNumber;
    private String cardHolder;
    private String cvv;
    public CreditCardPayment(String cardNumber, String cardHolder, String cvv) {
        this.cardNumber = cardNumber;
        this.cardHolder = cardHolder;
        this.cvv = cvv;
    }
    @Override
    public void pay(double amount) {
        System.out.println("使用信用卡支付 $" + amount);
        // 实际支付逻辑
    }
}
// 使用PayPal支付的策略实现
public class PayPalPayment implements PaymentStrategy {
    private String email;
    private String password;
    public PayPalPayment(String email, String password) {
        this.email = email;
        this.password = password;
    }
    @Override
    public void pay(double amount) {
        System.out.println("使用PayPal支付 $" + amount);
        // 实际支付逻辑
    }
}
// 使用比特币支付的策略实现
public class BitcoinPayment implements PaymentStrategy {
    private String walletAddress;
    public BitcoinPayment(String walletAddress) {
        this.walletAddress = walletAddress;
    }
    @Override
    public void pay(double amount) {
        System.out.println("使用比特币支付 $" + amount);
        // 实际支付逻辑
    }
}
上下文
笔者创建了一个 ShoppingCart 类,作为上下文,持有一个 PaymentStrategy 对象。ShoppingCart 类提供了添加商品和结账的方法,结账时使用当前的支付策略来完成支付。
public class ShoppingCart {
    private List<String> items;
    private PaymentStrategy paymentStrategy;
    public ShoppingCart() {
        this.items = new ArrayList<>();
    }
    public void addItem(String item) {
        items.add(item);
        System.out.println(item + " 已添加到购物车.");
    }
    public void setPaymentStrategy(PaymentStrategy paymentStrategy) {
        this.paymentStrategy = paymentStrategy;
    }
    public void checkout(double amount) {
        if (paymentStrategy == null) {
            System.out.println("请先选择支付方式.");
            return;
        }
        paymentStrategy.pay(amount);
        System.out.println("支付完成. 购物车已清空.");
        items.clear();
    }
}
使用策略模式
在主类中,笔者演示了如何通过 ShoppingCart 使用不同的支付策略来完成支付操作。客户端可以根据需要动态选择支付方式,而无需修改 ShoppingCart 类的代码。
public class Main {
    public static void main(String[] args) {
        ShoppingCart cart = new ShoppingCart();
        cart.addItem("书籍");
        cart.addItem("笔记本");
        // 选择信用卡支付
        PaymentStrategy creditCard = new CreditCardPayment("1234-5678-9012-3456", "张三", "123");
        cart.setPaymentStrategy(creditCard);
        cart.checkout(150.0);
        // 添加更多商品
        cart.addItem("耳机");
        // 选择PayPal支付
        PaymentStrategy payPal = new PayPalPayment("zhangsan@example.com", "securepassword");
        cart.setPaymentStrategy(payPal);
        cart.checkout(75.0);
        // 添加更多商品
        cart.addItem("手机");
        // 选择比特币支付
        PaymentStrategy bitcoin = new BitcoinPayment("1BoatSLRHtKNngkdXEeobR76b53LETtpyT");
        cart.setPaymentStrategy(bitcoin);
        cart.checkout(300.0);
    }
}
输出示例
书籍 已添加到购物车.
笔记本 已添加到购物车.
使用信用卡支付 $150.0
支付完成. 购物车已清空.
耳机 已添加到购物车.
使用PayPal支付 $75.0
支付完成. 购物车已清空.
手机 已添加到购物车.
使用比特币支付 $300.0
支付完成. 购物车已清空.
代码仓库
完整代码可访问以下链接:Java-Learning/src/com/DesignPattern/strategy_2 at main · sumingcheng/Java-Learning