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

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

文章目录

一、订单处理

场景假设:有一个订单处理系统,需要根据不同的订单类型(如普通订单、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
相关推荐
cheems9527几秒前
[SpringMVC] SpringWebMVC常见注解介绍
java·springmvc·注解
me832几秒前
【Java】Spring MVC接口执行流程详解:从前端请求到参数封装全解析(前端到底是怎么和后端交互的?)
java·spring·mvc
niucloud-admin3 分钟前
插件开发——upgrade 插件版本升级
java
vortex53 分钟前
Gradle 从入门到实战
java·gradle
代码丰4 分钟前
Zero Code Studio:LangChain4j 工具调用 + LangGraph4j 工作流双模式的 AI 网站生成系统
java·人工智能
云烟成雨TD32 分钟前
Spring AI 1.x 系列【28】基于内存和 MySQL 的多轮对话实现案例
java·人工智能·spring
Lyyaoo.34 分钟前
【JAVA基础面经】String、StringBuffer、StringBuilder
java·开发语言
TeamDev40 分钟前
JxBrowser 8.18.2 版本发布啦!
java·前端·跨平台·桌面应用·web ui·jxbrowser·浏览器控件
晴天sir44 分钟前
Redis 在业务中的几种典型用法
java·数据库·redis
WJX_KOI1 小时前
MemOS —— 为大语言模型 (LLMs) 和智能体打造的记忆操作系统。
java·人工智能·语言模型