策略模式 (Strategy)
在我们的日常生活中,我们会根据不同的场景和需求选择不同的解决方案。例如,早上我们可能选择跑步锻炼,下午则选择健身房,而在晚上可能选择瑜伽。这些行为的选择并不固定,而是基于不同的环境和需求。这种根据情况灵活切换策略的行为,就可以通过策略模式在编程中实现。
策略模式的核心思想是将不同的算法封装成独立的策略类,并让这些策略类可以互换。通过这种方式,我们可以根据实际情况灵活选择和切换算法或行为,而无需修改客户端代码。
趣味解读:为每种情况选择最佳方案
想象一下,你是一个厨师,每天都需要为不同的食客提供餐点。面对不同的需求,你有多种烹饪方法可供选择:
蒸:适合海鲜,能保留食材原汁原味。
炸:适合鸡肉,外酥里嫩,味道独特。
煮:适合蔬菜,清淡又健康。
你可以根据食客的要求(比如选择的食材和口味偏好)来灵活切换烹饪方式,而不需要每次都重新发明做饭的方法。这就像是策略模式一样,根据不同的情境切换不同的行为。
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
}
}
代码解析:
折扣策略接口 (
DiscountStrategy
):这是所有具体策略的父接口,定义了一个applyDiscount()
方法,用于计算价格的折扣。具体策略类:
FullReductionStrategy
、PercentageDiscountStrategy
和CashbackStrategy
分别实现了不同的折扣策略,分别对应满减、打折和返现的折扣计算方式。上下文类 (
ShoppingCart
):ShoppingCart
类持有一个DiscountStrategy
对象,并通过calculatePrice()
方法来计算商品价格。它的setDiscountStrategy()
方法可以在不同的情境下切换折扣策略。客户端代码:在
Main
类中,我们创建了一个购物车对象,并依次使用不同的折扣策略来计算商品价格。通过setDiscountStrategy()
方法,购物车对象可以灵活切换不同的折扣策略。
运行结果:
价格(满减): 200.0
价格(打折): 200.0
价格(返现): 220.0
实际应用场景
支付方式选择:在电商系统中,可以根据不同的支付方式(如信用卡支付、支付宝支付、微信支付等)采用不同的支付策略。
排序算法:在程序中,数据可能会有不同的排序方式(如升序、降序、按日期排序等),策略模式可以帮助我们灵活选择不同的排序算法。
搜索引擎算法:不同的搜索引擎可能会使用不同的算法进行索引和排名,策略模式可以用来管理和切换这些不同的搜索策略。
总结
策略模式通过将不同的算法封装成独立的策略类,让客户端代码能够根据具体需求灵活选择和切换算法,而不需要修改对象的实现。它避免了繁琐的条件判断,提升了系统的可扩展性和灵活性。策略模式特别适用于那些需要在多种算法或行为之间切换的场景,能够使系统在不同的情境下提供最佳的解决方案。