首页 > 编程语言 >【Java教程】Day20-21 设计模式:行为型模式——策略模式

【Java教程】Day20-21 设计模式:行为型模式——策略模式

时间:2025-01-07 19:02:29浏览次数:14  
标签:total Java 策略 折扣 模式 算法 设计模式 BigDecimal

1. 引言

策略模式(Strategy Pattern)是一种行为型设计模式,它定义了一系列的算法,将它们封装起来,并使得它们可以相互替换。策略模式的主要目的是使得算法可以独立于使用它的客户而变化。它常用于需要根据不同条件选择不同算法的场景。

在Java的标准库中,策略模式得到了广泛的应用,特别是在排序等常见操作中。通过策略模式,我们可以在运行时动态选择算法,而不需要修改原有代码。

2. 策略模式的结构

策略模式包含以下几个核心部分:

  1. 策略接口(Strategy):定义一组算法或行为的接口。

  2. 具体策略类(ConcreteStrategy):实现策略接口,封装具体的算法。

  3. 上下文类(Context):持有一个策略对象,并提供方法来切换策略,供客户端使用。

2.1 策略接口

策略接口定义了算法的公共方法,供具体策略类实现:

javapublic interface DiscountStrategy {    // 计算折扣额度:    BigDecimal getDiscount(BigDecimal total);}

 

2.2 具体策略类

不同的策略实现该接口,根据不同的规则进行计算。我们可以实现多个策略,例如普通用户折扣、满减折扣等。

javapublic 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 上下文类

上下文类持有一个策略对象,并允许在运行时根据需求切换策略:

javapublic 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 使用示例

使用策略模式的核心优势是可以灵活地切换策略。以下是一个完整的示例,展示了如何根据不同的折扣策略计算购物车总价。

javapublic 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.00Prime会员折扣: 80.00

 

3. 策略模式的应用场景

策略模式非常适用于以下几种场景:

  • 需要多种算法的场景:如果有多个算法可以执行同样的任务(例如排序、折扣计算等),策略模式可以将这些算法封装起来,并在运行时进行选择。

  • 算法或行为变化频繁:当系统中算法或行为会频繁变化时,使用策略模式可以避免修改现有代码,只需添加新的策略类即可。

  • 避免大量的if-else判断:当不同条件下执行不同的行为时,策略模式可以避免复杂的条件判断,增强代码的可维护性。

4. Java标准库中的策略模式应用

策略模式在Java的标准库中有很多应用,最典型的就是Arrays.sort()方法的实现。我们来看一个例子,如何使用策略模式实现忽略大小写的排序。

javaimport 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对象,它就是一种策略。在排序时,可以传入不同的比较策略,例如按字典顺序排序,按字符串长度排序等。

javaArrays.sort(array, (s1, s2) -> -s1.compareTo(s2));  // 使用倒序排序策略

 

5. 策略模式的优缺点

5.1 优点

  1. 增强了灵活性:策略模式允许在运行时动态选择不同的策略算法,这使得系统更加灵活。

  2. 符合开闭原则:通过扩展策略类来增加新功能,不需要修改现有的代码。

  3. 简化代码:避免了大量的if-elseswitch语句,使代码更加简洁和可维护。

5.2 缺点

  1. 增加了类的数量:每一种策略都需要定义一个具体的策略类,当策略多时,会增加类的数量。

  2. 客户端需要知道所有的策略:客户端需要知道有哪些策略,并负责选择使用哪个策略。

6. 小结

策略模式的核心思想是将算法封装在独立的策略类中,使得算法可以在运行时被动态切换。通过策略模式,我们能够实现不同策略之间的灵活切换,避免了冗长的if-elseswitch语句,使得代码更加简洁和易于维护。策略模式在实际项目中有广泛的应用,特别是在需要根据不同条件选择不同算法或行为时,非常有效。

通过扩展策略,可以轻松地增加新的行为,而不需要修改现有的代码,符合开闭原则,使得系统更具扩展性。

7. 练习

假设网站对于Prime会员的折扣规则是:在满100减20的基础上,再对Prime会员进行七折优惠。请实现这一新策略,并将其与其他策略结合使用。

 

 

 

标签:total,Java,策略,折扣,模式,算法,设计模式,BigDecimal
From: https://blog.csdn.net/max202011161630/article/details/144856974

相关文章