在我们的日常生活中,我们会根据不同的场景和需求选择不同的解决方案。例如,早上我们可能选择跑步锻炼,下午则选择健身房,而在晚上可能选择瑜伽。这些行为的选择并不固定,而是基于不同的环境和需求。这种根据情况灵活切换策略的行为,就可以通过策略模式在编程中实现。

策略模式的核心思想是将不同的算法封装成独立的策略类,并让这些策略类可以互换。通过这种方式,我们可以根据实际情况灵活选择和切换算法或行为,而无需修改客户端代码。

趣味解读:为每种情况选择最佳方案

想象一下,你是一个厨师,每天都需要为不同的食客提供餐点。面对不同的需求,你有多种烹饪方法可供选择:

  • :适合海鲜,能保留食材原汁原味。

  • :适合鸡肉,外酥里嫩,味道独特。

  • :适合蔬菜,清淡又健康。

你可以根据食客的要求(比如选择的食材和口味偏好)来灵活切换烹饪方式,而不需要每次都重新发明做饭的方法。这就像是策略模式一样,根据不同的情境切换不同的行为。

Java代码案例:打折策略

假设你正在开发一个电商系统,需要根据不同的促销活动计算商品的折扣。为了应对各种促销策略(如“满减”、“折扣”、“返现”),我们可以使用策略模式将每种折扣策略封装成独立的类,方便在不同场景下切换。

// 1. 折扣策略接口
interface DiscountStrategy {
    double applyDiscount(double price);
}
​
// 2. 具体策略 - 满减
class FullReductionStrategy implements DiscountStrategy {
    private double threshold;
    private double reduction;
​
    public FullReductionStrategy(double threshold, double reduction) {
        this.threshold = threshold;
        this.reduction = reduction;
    }
​
    @Override
    public double applyDiscount(double price) {
        if (price >= threshold) {
            return price - reduction;
        }
        return price;
    }
}
​
// 3. 具体策略 - 打折
class PercentageDiscountStrategy implements DiscountStrategy {
    private double discountRate;
​
    public PercentageDiscountStrategy(double discountRate) {
        this.discountRate = discountRate;
    }
​
    @Override
    public double applyDiscount(double price) {
        return price * (1 - discountRate);
    }
}
​
// 4. 具体策略 - 返现
class CashbackStrategy implements DiscountStrategy {
    private double cashback;
​
    public CashbackStrategy(double cashback) {
        this.cashback = cashback;
    }
​
    @Override
    public double applyDiscount(double price) {
        return price - cashback;
    }
}
​
// 5. 上下文 - 购物车
class ShoppingCart {
    private DiscountStrategy discountStrategy;
​
    public ShoppingCart(DiscountStrategy discountStrategy) {
        this.discountStrategy = discountStrategy;
    }
​
    public void setDiscountStrategy(DiscountStrategy discountStrategy) {
        this.discountStrategy = discountStrategy;
    }
​
    public double calculatePrice(double originalPrice) {
        return discountStrategy.applyDiscount(originalPrice);
    }
}
​
// 6. 客户端代码
public class Main {
    public static void main(String[] args) {
        // 创建不同的折扣策略
        DiscountStrategy fullReduction = new FullReductionStrategy(200, 50);
        DiscountStrategy percentageDiscount = new PercentageDiscountStrategy(0.2);
        DiscountStrategy cashback = new CashbackStrategy(30);
​
        // 创建购物车对象并设置折扣策略
        ShoppingCart cart = new ShoppingCart(fullReduction);
        double price1 = cart.calculatePrice(250);  // 使用满减策略
        System.out.println("价格(满减): " + price1);  // 价格:200.0
​
        cart.setDiscountStrategy(percentageDiscount);
        double price2 = cart.calculatePrice(250);  // 使用打折策略
        System.out.println("价格(打折): " + price2);  // 价格:200.0
​
        cart.setDiscountStrategy(cashback);
        double price3 = cart.calculatePrice(250);  // 使用返现策略
        System.out.println("价格(返现): " + price3);  // 价格:220.0
    }
}

代码解析:

  1. 折扣策略接口 (DiscountStrategy):这是所有具体策略的父接口,定义了一个 applyDiscount() 方法,用于计算价格的折扣。

  2. 具体策略类FullReductionStrategyPercentageDiscountStrategyCashbackStrategy 分别实现了不同的折扣策略,分别对应满减、打折和返现的折扣计算方式。

  3. 上下文类 (ShoppingCart)ShoppingCart 类持有一个 DiscountStrategy 对象,并通过 calculatePrice() 方法来计算商品价格。它的 setDiscountStrategy() 方法可以在不同的情境下切换折扣策略。

  4. 客户端代码:在 Main 类中,我们创建了一个购物车对象,并依次使用不同的折扣策略来计算商品价格。通过 setDiscountStrategy() 方法,购物车对象可以灵活切换不同的折扣策略。

运行结果:

价格(满减): 200.0
价格(打折): 200.0
价格(返现): 220.0

实际应用场景

  1. 支付方式选择:在电商系统中,可以根据不同的支付方式(如信用卡支付、支付宝支付、微信支付等)采用不同的支付策略。

  2. 排序算法:在程序中,数据可能会有不同的排序方式(如升序、降序、按日期排序等),策略模式可以帮助我们灵活选择不同的排序算法。

  3. 搜索引擎算法:不同的搜索引擎可能会使用不同的算法进行索引和排名,策略模式可以用来管理和切换这些不同的搜索策略。

总结

策略模式通过将不同的算法封装成独立的策略类,让客户端代码能够根据具体需求灵活选择和切换算法,而不需要修改对象的实现。它避免了繁琐的条件判断,提升了系统的可扩展性和灵活性。策略模式特别适用于那些需要在多种算法或行为之间切换的场景,能够使系统在不同的情境下提供最佳的解决方案。