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

在这里插入图片描述

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

文章目录

  • 一、订单处理
  • 二、策略模式
  • 三、策略模式的核心组成
  • 四、运用策略模式
  • 五、策略模式的应用场景
  • 六、小结
  • 推荐阅读

一、订单处理

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

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

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

    // 正常折扣策略
    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. 创建环境类:我们需要一个环境类来持有策略对象,并根据客户端的选择来执行相应的策略。

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

    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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/747795.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

使用CDN方式创建Vue3.0应用程序

CDN 的全称是 content delivery network,即内容分发网络。它是构建在现在的互联网基础之上的一层智能虚拟网络,依靠部署在各地的边缘服务器,通过中心平台的负载均衡、内容分发和调度等功能模块,使用户就近获取所需内容&#xff0c…

2023 年度国家科学技术奖励公布

人不走空 🌈个人主页:人不走空 💖系列专栏:算法专题 ⏰诗词歌赋:斯是陋室,惟吾德馨 目录 🌈个人主页:人不走空 💖系列专栏:算法专题 ⏰诗词歌…

引用别的组件

在脚本中,也可以引用别的物体下的组件。 第一种办法, (1)添加一个变量, public GameObject bgmNode ; 然后在检查器里指定这个引用。 例如:在背景音乐空物体下面有个Audio Source组件 游戏主控脚本代码…

Python | Leetcode Python题解之第200题岛屿数量

题目&#xff1a; 题解&#xff1a; class Solution:def dfs(self, grid, r, c):grid[r][c] 0nr, nc len(grid), len(grid[0])for x, y in [(r - 1, c), (r 1, c), (r, c - 1), (r, c 1)]:if 0 < x < nr and 0 < y < nc and grid[x][y] "1":self.d…

网约车停运损失费:2、协商过程

目录 &#x1f345;点击这里查看所有博文 随着自己工作的进行&#xff0c;接触到的技术栈也越来越多。给我一个很直观的感受就是&#xff0c;某一项技术/经验在刚开始接触的时候都记得很清楚。往往过了几个月都会忘记的差不多了&#xff0c;只有经常会用到的东西才有可能真正记…

Jackson和fastjson解决序列化时字段属性大小写改变的问题

在部分特殊场景下&#xff0c;我们可能会把实体的字段属性改成全部大写&#xff0c;但是在返回前端时&#xff0c;字段会被序列化成小写。 比如我们有一个这个类属性都是大写&#xff1a; 后端接口是这样的 然后我们请求后&#xff0c;会发现我们的字段被变成全部小写的。 …

windows USB 设备驱动开发-总章

通用串行总线 (USB) 提供可扩展的即插即用串行接口&#xff0c;确保外围设备的标准、低成本的连接。 USB 设备包括键盘、鼠标、游戏杆、打印机、扫描仪、存储设备、调制解调器、视频会议摄像头等。USB-IF 是一个特别兴趣组 (SIG)&#xff0c;负责维护官方 USB 规范、测试规范和…

vs code + Keil Assistant 配置 Keil 单片机开发

1、 先安装vscode完成后 安装插件 2 安装C/C 与 keil Assistant 需说明一下 Assistant 1.7.0版本有bug F7按不了 所以安装1.6.2版本 以下是我的安装插件 EMBEDDED IDE 可安装 可不安装 随便你 3 配置 Assistant 4、设置C/C 目录 ${workspaceFolder}/**D:/Keil_v5/C51/INC/**…

构建 Audio Unit 应用程序

构建 Audio Unit 应用程序 构建 Audio Unit 应用程序从选择设计模式开始I/O Pass ThroughI/O Without a Render Callback FunctionI/O with a Render Callback FunctionOutput-Only with a Render Callback Function其他设计模式 构建应用程序配置 audio session指定 audio uni…

Linux系统安装和卸载nginx

&#x1f4d6;Linux系统安装和卸载nginx ✅下载✅安装✅启动nginx✅安装成系统服务✅常见问题&#xff1a;80端口被占用了✅卸载✅目录结构 以下介绍的是以源码编译安装方式&#xff1a; ✅下载 官方地址&#xff1a;https://nginx.org/en/download.html 123云盘地址&#x…

MySQL表解锁

查看锁信息 show full processlist 如果一个表被锁定了&#xff0c;会有一个 “Waiting for table metadata lock” 的提示&#xff0c;表明该表正在等待锁定。 解锁表 删除state上有值的事务 kill query 事务id 表解锁完成

2024南京国际自有品牌产品博览会

展会名称&#xff1a;2024南京国际自有品牌产品博览会 展会时间&#xff1a;2024年10月11-13日 展会地点&#xff1a;南京国际博览中心 展览规模&#xff1a;36000平米 详询主办方陆先生 I38&#xff08;前三位&#xff09; I82I&#xff08;中间四位&#xff09; 9I72&…

[XYCTF新生赛2024]-PWN:ptmalloc2 it‘s myheap plus解析(glibc2.35,堆中的栈迁移,orw)

查看保护 查看ida 思路&#xff1a; 泄露libc和堆地址就不多说了&#xff0c;fastbin duf也不解释了。这里主要是利用fastbin duf在environ附近创建堆块&#xff0c;泄露environ中的栈地址&#xff0c;然后就利用fastbin duf修改rbp和返回地址进行栈迁移了&#xff0c;迁移目标…

Apache APISIX遇到504超时的解决办法

说明&#xff1a; Apache APISIX版本&#xff1a;v3.9.0Apache APISIX Dashboard版本&#xff1a;v3.0.1 当使用Apache APISIX开源网关&#xff0c;通过接口上传或下载大文件等时&#xff0c;出现如下“504 Gateway Time-out”错误信息&#xff0c;它表示网关或代理服务器未能…

Spring Cloud - nacos +ubuntu环境搭建

1、安装ubuntu虚拟环境 VMware虚拟机安装Ubuntu与配置Ubuntu&#xff08;超详细教程&#xff09; 2、docker环境安装 1、apt-get install apt-transport-https ca-certificates curl gnupg-agent software-properties-common 2、curl -fsSL https://mirrors.ustc.edu.cn/docke…

【JavaScript】BOM编程

目录 一、BOM编程是什么 二、window对象的常用方法 1、弹窗API方法 2、计时器任务方法 三、window对象的属性对象常用方法 1、history网页浏览历史 2、location地址栏 3、数据存储属性对象 4、console控制台 一、BOM编程是什么 当我们使用浏览器打开一个网页窗口时&#xff0c;…

mysql索引、事务以及存储引擎

目录 一、索引 1&#xff09;索引定义 ​2&#xff09;工作方式 3&#xff09;创建索引的依据 4&#xff09;索引类型 1、index普通索引 2、unique唯一索引 3、主键索引 4、多列组合索引 5、全文索引 5&#xff09;删除索引 6&#xff09;查看索引 7&#xff09;索…

数字化世界的守卫之防火墙

在这个数字化的时代&#xff0c;我们的电脑和手机就像是一座座繁华的城市&#xff0c;而病毒和黑客则是那些潜伏在暗处的敌人。但别担心&#xff0c;我们有一群忠诚的守卫——“防火墙”&#xff0c;它们日夜守护着我们的数字家园。 1. 病毒&#xff1a;数字世界的“瘟疫” 想象…

文心智能体平台介绍和应用:制作你的智能体(运维小帮手)

这是我自己制作的智能体 大家可以了解一下&#xff01; 运维小帮手&#xff01;https://mbd.baidu.com/ma/s/tE19dqvr 文心智能体平台官网首页 点击跳转&#xff01;https://agents.baidu.com/ 什么是智能体平台&#xff1f; 文心智能体平台&#xff08;Wenxin Intelligen…

安装与配置:MySQL的环境搭建之旅(二)

目录 引言&#xff1a;从理论到实践的跨越 一、安装MySQL&#xff1a;跨平台的便捷指南 Windows环境 Linux环境 macOS环境 二、基本配置&#xff1a;端口设置与字符集选择 三、从零到一的蜕变 引言&#xff1a;从理论到实践的跨越 在前一章节《MySQL简介》中&#xff0c…