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

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

文章目录

一、订单处理

场景假设:有一个订单处理系统,需要根据不同的订单类型(如普通订单、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
相关推荐
m0_7482451730 分钟前
Web第一次作业
java
小码的头发丝、30 分钟前
Java进阶学习笔记|面向对象
java·笔记·学习
m0_5485147734 分钟前
前端Pako.js 压缩解压库 与 Java 的 zlib 压缩与解压 的互通实现
java·前端·javascript
坊钰1 小时前
【Java 数据结构】移除链表元素
java·开发语言·数据结构·学习·链表
chenziang11 小时前
leetcode hot100 LRU缓存
java·开发语言
会说法语的猪1 小时前
springboot实现图片上传、下载功能
java·spring boot·后端
码农老起1 小时前
IntelliJ IDEA 基本使用教程及Spring Boot项目搭建实战
java·ide·intellij-idea
m0_748239831 小时前
基于web的音乐网站(Java+SpringBoot+Mysql)
java·前端·spring boot
时雨h1 小时前
RuoYi-ue前端分离版部署流程
java·开发语言·前端