策略模式(Strategy Pattern)
策略模式(Strategy Pattern)是一种行为设计模式,它定义了一系列的算法,并将每个算法封装起来,使它们可以相互替换。策略模式让算法的变化独立于使用算法的客户端。以下从多个方面详细介绍策略模式。
模式结构与角色
策略模式主要包含以下几个角色:
- 策略接口(Strategy):定义了所有具体策略类必须实现的公共接口,通常包含一个或多个抽象方法,这些方法代表了算法的行为。
- 具体策略类(Concrete Strategy):实现了策略接口,提供了具体的算法实现。每个具体策略类封装了一种特定的算法。
- 上下文类(Context):维护一个对策略接口的引用,负责根据客户端的需求选择并使用具体的策略。上下文类将具体的算法委托给具体策略类来执行。
代码示例
以下是一个简单的策略模式示例,模拟一个购物系统中的不同折扣策略:
// 策略接口:折扣策略
interface DiscountStrategy {
double applyDiscount(double price);
}
// 具体策略类:无折扣策略
class NoDiscountStrategy implements DiscountStrategy {
@Override
public double applyDiscount(double price) {
return price;
}
}
// 具体策略类:10% 折扣策略
class TenPercentDiscountStrategy implements DiscountStrategy {
@Override
public double applyDiscount(double price) {
return price * 0.9;
}
}
// 具体策略类:20% 折扣策略
class TwentyPercentDiscountStrategy implements DiscountStrategy {
@Override
public double applyDiscount(double price) {
return price * 0.8;
}
}
// 上下文类:购物车
class ShoppingCart {
private DiscountStrategy discountStrategy;
public ShoppingCart(DiscountStrategy discountStrategy) {
this.discountStrategy = discountStrategy;
}
public void setDiscountStrategy(DiscountStrategy discountStrategy) {
this.discountStrategy = discountStrategy;
}
public double calculateTotal(double price) {
return discountStrategy.applyDiscount(price);
}
}
// 客户端代码
public class StrategyPatternExample {
public static void main(String[] args) {
// 创建不同的折扣策略
DiscountStrategy noDiscount = new NoDiscountStrategy();
DiscountStrategy tenPercentDiscount = new TenPercentDiscountStrategy();
DiscountStrategy twentyPercentDiscount = new TwentyPercentDiscountStrategy();
// 创建购物车并使用无折扣策略
ShoppingCart cart = new ShoppingCart(noDiscount);
double price = 100;
System.out.println("无折扣时总价: " + cart.calculateTotal(price));
// 切换到 10% 折扣策略
cart.setDiscountStrategy(tenPercentDiscount);
System.out.println("10% 折扣时总价: " + cart.calculateTotal(price));
// 切换到 20% 折扣策略
cart.setDiscountStrategy(twentyPercentDiscount);
System.out.println("20% 折扣时总价: " + cart.calculateTotal(price));
}
}
代码解释
- 策略接口
DiscountStrategy
:定义了applyDiscount()
方法,用于计算折扣后的价格。 - 具体策略类(
NoDiscountStrategy
、TenPercentDiscountStrategy
、TwentyPercentDiscountStrategy
):实现了DiscountStrategy
接口,分别提供了无折扣、10% 折扣和 20% 折扣的具体算法。 - 上下文类
ShoppingCart
:维护了一个DiscountStrategy
类型的引用,通过构造函数或setDiscountStrategy()
方法来设置具体的折扣策略。calculateTotal()
方法将计算总价的任务委托给具体的折扣策略类。 - 客户端代码:创建了不同的折扣策略对象和购物车对象,通过调用购物车的
calculateTotal()
方法计算不同折扣策略下的总价,并可以动态切换折扣策略。
优点
- 可扩展性:策略模式符合开闭原则,当需要添加新的算法时,只需要创建一个新的具体策略类,而不需要修改现有的代码。
- 代码复用:每个具体策略类封装了一个独立的算法,这些算法可以在不同的上下文中复用。
- 消除条件判断:避免了使用大量的
if - else
或switch - case
语句来选择不同的算法,使代码更加简洁和可读。
缺点
- 类的数量增加:随着策略的增加,具体策略类的数量也会增加,导致系统中的类数量增多,增加了系统的复杂度。
- 客户端需要了解策略:客户端需要了解不同的策略及其适用场景,才能正确选择合适的策略,这增加了客户端的使用难度。
应用场景
- 算法选择:当一个系统需要根据不同的情况选择不同的算法时,如排序算法、加密算法等,可以使用策略模式。
- 支付方式选择:在电商系统中,用户可以选择不同的支付方式(如支付宝、微信支付、银行卡支付等),每种支付方式可以看作是一个具体的策略。
- 游戏中的角色行为:在游戏开发中,角色可能有不同的行为模式(如攻击模式、防御模式、逃跑模式等),可以使用策略模式来实现角色在不同模式下的行为。
Java设计模式 文章被收录于专栏
设计模式是软件开发中针对反复出现的问题所总结归纳出的通用解决方案,它可以帮助开发者更高效地构建软件系统,提升代码的可维护性、可扩展性和可复用性。