1. 引言
策略模式(Strategy Pattern)是一种行为型设计模式,它定义了一系列的算法,将它们封装起来,并使得它们可以相互替换。策略模式的主要目的是使得算法可以独立于使用它的客户而变化。它常用于需要根据不同条件选择不同算法的场景。
在Java的标准库中,策略模式得到了广泛的应用,特别是在排序等常见操作中。通过策略模式,我们可以在运行时动态选择算法,而不需要修改原有代码。
2. 策略模式的结构
策略模式包含以下几个核心部分:
-
策略接口(Strategy):定义一组算法或行为的接口。
-
具体策略类(ConcreteStrategy):实现策略接口,封装具体的算法。
-
上下文类(Context):持有一个策略对象,并提供方法来切换策略,供客户端使用。
2.1 策略接口
策略接口定义了算法的公共方法,供具体策略类实现:
java
public interface DiscountStrategy {
// 计算折扣额度:
BigDecimal getDiscount(BigDecimal total);
}
2.2 具体策略类
不同的策略实现该接口,根据不同的规则进行计算。我们可以实现多个策略,例如普通用户折扣、满减折扣等。
java
public class UserDiscountStrategy implements DiscountStrategy {
public BigDecimal getDiscount(BigDecimal total) {
// 普通会员打九折:
return total.multiply(new BigDecimal("0.1")).setScale(2, RoundingMode.DOWN);
}
}
javapublic class OverDiscountStrategy implements DiscountStrategy {
public BigDecimal getDiscount(BigDecimal total) {
// 满100减20优惠:
return total.compareTo(BigDecimal.valueOf(100)) >= 0 ? BigDecimal.valueOf(20) : BigDecimal.ZERO;
}
}
2.3 上下文类
上下文类持有一个策略对象,并允许在运行时根据需求切换策略:
java
public class DiscountContext {
// 默认使用普通会员折扣
private DiscountStrategy strategy = new UserDiscountStrategy();
// 允许客户端设置新策略:
public void setStrategy(DiscountStrategy strategy) {
this.strategy = strategy;
}
// 计算价格方法
public BigDecimal calculatePrice(BigDecimal total) {
return total.subtract(this.strategy.getDiscount(total)).setScale(2);
}
}
2.4 使用示例
使用策略模式的核心优势是可以灵活地切换策略。以下是一个完整的示例,展示了如何根据不同的折扣策略计算购物车总价。
java
public class Main {
public static void main(String[] args) {
DiscountContext ctx = new DiscountContext();
// 默认使用普通会员折扣
BigDecimal pay1 = ctx.calculatePrice(BigDecimal.valueOf(105));
System.out.println("普通会员折扣: " + pay1);
// 使用满减折扣
ctx.setStrategy(new OverDiscountStrategy());
BigDecimal pay2 = ctx.calculatePrice(BigDecimal.valueOf(105));
System.out.println("满减折扣: " + pay2);
// 使用Prime会员折扣
ctx.setStrategy(new PrimeDiscountStrategy());
BigDecimal pay3 = ctx.calculatePrice(BigDecimal.valueOf(105));
System.out.println("Prime会员折扣: " + pay3);
}
}
2.5 输出示例
text
普通会员折扣: 94.50
满减折扣: 85.00
Prime会员折扣: 80.00
3. 策略模式的应用场景
策略模式非常适用于以下几种场景:
-
需要多种算法的场景:如果有多个算法可以执行同样的任务(例如排序、折扣计算等),策略模式可以将这些算法封装起来,并在运行时进行选择。
-
算法或行为变化频繁:当系统中算法或行为会频繁变化时,使用策略模式可以避免修改现有代码,只需添加新的策略类即可。
-
避免大量的
if-else
判断:当不同条件下执行不同的行为时,策略模式可以避免复杂的条件判断,增强代码的可维护性。
4. Java标准库中的策略模式应用
策略模式在Java的标准库中有很多应用,最典型的就是Arrays.sort()
方法的实现。我们来看一个例子,如何使用策略模式实现忽略大小写的排序。
java
import java.util.Arrays;
public class Main {
public static void main(String[] args) {
String[] array = { "apple", "Pear", "Banana", "orange" };
Arrays.sort(array, String::compareToIgnoreCase); // 使用忽略大小写的排序策略
System.out.println(Arrays.toString(array));
}
}
这里,Arrays.sort()
方法接收一个Comparator
对象,它就是一种策略。在排序时,可以传入不同的比较策略,例如按字典顺序排序,按字符串长度排序等。
java
Arrays.sort(array, (s1, s2) -> -s1.compareTo(s2)); // 使用倒序排序策略
5. 策略模式的优缺点
5.1 优点
-
增强了灵活性:策略模式允许在运行时动态选择不同的策略算法,这使得系统更加灵活。
-
符合开闭原则:通过扩展策略类来增加新功能,不需要修改现有的代码。
-
简化代码:避免了大量的
if-else
或switch
语句,使代码更加简洁和可维护。
5.2 缺点
-
增加了类的数量:每一种策略都需要定义一个具体的策略类,当策略多时,会增加类的数量。
-
客户端需要知道所有的策略:客户端需要知道有哪些策略,并负责选择使用哪个策略。
6. 小结
策略模式的核心思想是将算法封装在独立的策略类中,使得算法可以在运行时被动态切换。通过策略模式,我们能够实现不同策略之间的灵活切换,避免了冗长的if-else
或switch
语句,使得代码更加简洁和易于维护。策略模式在实际项目中有广泛的应用,特别是在需要根据不同条件选择不同算法或行为时,非常有效。
通过扩展策略,可以轻松地增加新的行为,而不需要修改现有的代码,符合开闭原则,使得系统更具扩展性。
7. 练习
假设网站对于Prime会员的折扣规则是:在满100减20的基础上,再对Prime会员进行七折优惠。请实现这一新策略,并将其与其他策略结合使用。
标签:total,Java,策略,折扣,模式,算法,设计模式,BigDecimal From: https://blog.csdn.net/max202011161630/article/details/144856974