【设计模式】行为型-策略模式

策略模式,如春风吹过,随心所欲,变幻无穷,每一丝风都是一种选择。

文章目录

一、订单处理

场景假设:有一个订单处理系统,需要根据不同的订单类型(如普通订单、VIP 订单、超级 VIP 订单)来计算订单的折扣金额。

java 复制代码
class OrderProcessor {
    public double calculateDiscount(Order order) {
        double originalPrice = order.getTotalPrice();
        double discount = 0.0;

        if (order.getType() == OrderType.REGULAR) {
            // 正常订单折扣计算
            discount = originalPrice * 0.1;
        } else if (order.getType() == OrderType.VIP) {
            // VIP 订单折扣计算
            discount = originalPrice * 0.2;
        } else if (order.getType() == OrderType.SUPER_VIP) {
            // 超级 VIP 订单折扣计算
            discount = originalPrice * 0.3;
        } // ... 更多订单类型

        return discount;
    }
}

上面的代码虽然能够实现需求,但存在以下问题:

  1. 可扩展性差:如果需要添加更多的订单类型,我们必须修改原有的代码,违反了开放-封闭原则。
  2. 代码重复:不同订单类型的折扣计算逻辑被硬编码在同一个方法中,导致代码重复。

二、策略模式

策略模式(Strategy Pattern)是一种行为型设计模式,它允许在运行时选择算法的行为。在策略模式中,可以定义一系列的算法,把它们封装起来,并且使它们可以互相替换。这样,客户端在使用算法时可以根据需求动态地选择其中一种算法,而不需要更改其代码。

三、策略模式的核心组成

策略模式的核心组成部分包括以下几个要素:

  1. 策略接口(Strategy Interface):这是一个接口或抽象类,定义所有具体策略类必须实现的方法。策略接口通常会声明一个或多个方法,用于执行具体的算法或操作。
  2. 具体策略类(Concrete Strategies):这些类实现了策略接口,每个具体策略类都代表一个独立的算法或操作。它们实现了策略接口中定义的方法,提供了算法的具体实现。
  3. 上下文(Context):上下文类持有一个策略接口的引用,通常会包含一个设置策略的方法,用于动态地切换不同的具体策略。上下文类通过策略接口与具体策略类进行交互,根据需要调用具体策略类的方法。
  4. 客户端(Client):客户端是使用策略模式的类或模块。它通过实例化上下文对象,并设置具体策略类来使用相应的算法或操作。

这个类图展示了策略模式的核心组成部分:

  • Strategy 接口定义了所有具体策略类必须实现的算法方法 algorithm()
  • ConcreteStrategyA ConcreteStrategyB 是具体的策略类,实现了 Strategy 接口,分别提供了不同的算法实现。
  • Context 类持有一个 Strategy 接口的引用,在运行时可以动态地切换具体的策略。它提供了一个 setStrategy() 方法来设置当前的策略,并且通过 contextInterface() 方法调用当前策略的算法。

四、运用策略模式

场景假设:有一个订单处理系统,需要根据不同的订单类型(如普通订单、VIP 订单、超级 VIP 订单)来计算订单的折扣金额。

  1. 定义抽象策略接口:首先,我们需要定义一个抽象策略接口,该接口包含一个计算折扣价格的方法。这个接口将作为不同折扣策略的基类。

    java 复制代码
    // 抽象策略接口
    interface DiscountStrategy {
        double calculateDiscount(double originalPrice);
    }
  2. 创建具体策略类:接下来,我们为不同的折扣方式创建具体策略类。每个具体策略类都实现了折扣策略接口,并提供了自己的折扣计算逻辑。

    java 复制代码
    // 正常折扣策略
    class RegularDiscountStrategy implements DiscountStrategy {
        @Override
        public double calculateDiscount(double originalPrice) {
            // 根据正常折扣计算折后价格
            return originalPrice * 0.9;
        }
    }
    
    // VIP 折扣策略
    class VIPDiscountStrategy implements DiscountStrategy {
        @Override
        public double calculateDiscount(double originalPrice) {
            // VIP 折扣计算
            return originalPrice * 0.8;
        }
    }
    
    // 超级 VIP 折扣策略
    class SuperVIPDiscountStrategy implements DiscountStrategy {
        @Override
        public double calculateDiscount(double originalPrice) {
            // 超级 VIP 折扣计算
            return originalPrice * 0.7;
        }
    }
  3. 创建环境类:我们需要一个环境类来持有策略对象,并根据客户端的选择来执行相应的策略。

    java 复制代码
    // 环境类
    class OrderProcessor {
        private DiscountStrategy discountStrategy;
    
        public void setDiscountStrategy(DiscountStrategy strategy) {
            this.discountStrategy = strategy;
        }
    
        public double calculateDiscountedPrice(double originalPrice) {
            return discountStrategy.calculateDiscount(originalPrice);
        }
    }
  4. 客户端代码:在客户端代码中,我们可以根据订单类型选择不同的折扣策略。

    java 复制代码
    public class Client {
        public static void main(String[] args) {
            OrderProcessor orderProcessor = new OrderProcessor();
    
            // 选择不同的折扣策略
            orderProcessor.setDiscountStrategy(new RegularDiscountStrategy());
            double discountedPrice1 = orderProcessor.calculateDiscountedPrice(100.0);
            System.out.println("正常折扣后价格:" + discountedPrice1);
    
            orderProcessor.setDiscountStrategy(new VIPDiscountStrategy());
            double discountedPrice2 = orderProcessor.calculateDiscountedPrice(100.0);
            System.out.println("VIP 折扣后价格:" + discountedPrice2);
        }
    }

五、策略模式的应用场景

策略模式常见于以下场景:

  1. 行为切换:当系统中有多个类,这些类之间的区别仅在于它们的行为不同时,可以使用策略模式。通过策略模式,用户对象可以在这些行为中动态地选择一个,将不同的行为封装到不同的类中,每个行为对应一种策略。
  2. 算法选择:如果系统中需要在几种算法中动态地选择一种,策略模式也适用。例如,计算方式可以有不同的实现,比如加法策略和乘法策略,用户可以根据需要选择不同的策略。

六、小结

策略模式是一种简单但非常实用的设计模式,它能有效地管理算法的选择和切换,提高系统的灵活性和可维护性。在面对需要动态选择算法或行为的问题时,策略模式是一个值得考虑的解决方案。

推荐阅读

  1. Spring 三级缓存
  2. 深入了解 MyBatis 插件:定制化你的持久层框架
  3. Zookeeper 注册中心:单机部署
  4. 【JavaScript】探索 JavaScript 中的解构赋值
  5. 深入理解 JavaScript 中的 Promise、async 和 await
相关推荐
蓝澈11212 分钟前
弗洛伊德(Floyd)算法-各个顶点之间的最短路径问题
java·数据结构·动态规划
再见晴天*_*10 分钟前
logback 日志不打印
java·服务器·logback
幽络源小助理18 分钟前
SpringBoot基于JavaWeb的城乡居民基本医疗信息管理系统
java·spring boot·学习
欧阳有财21 分钟前
[java八股文][Mysql面试篇]日志
java·mysql·面试
TDengine (老段)30 分钟前
使用 StatsD 向 TDengine 写入
java·大数据·数据库·时序数据库·iot·tdengine·涛思数据
真实的菜32 分钟前
JVM类加载系统详解:深入理解Java类的生命周期
java·开发语言·jvm
N_NAN_N1 小时前
类图+案例+代码详解:软件设计模式----原型模式
java·设计模式·原型模式
佛祖保佑永不宕机1 小时前
maven引入本地jar包
java·maven·jar
默默coding的程序猿1 小时前
3.前端和后端参数不一致,后端接不到数据的解决方案
java·前端·spring·ssm·springboot·idea·springcloud
在未来等你2 小时前
JVM调优实战 Day 15:云原生环境下的JVM配置
java·jvm·性能优化·虚拟机·调优