Spring设计模式-实战篇之策略模式 + 工厂模式

案例:使用策略模式和工厂模式优化大量的if-else

        原先代码如下,有衣服、零食、蔬菜三种类型的商品,并且每一类满减折扣不一样,如果使用if-else,代码会显得非常冗长,并且大量的if-else很容易眼花导致维护代码时改错地方,不利于后期维护和扩展。

 public static double calculatePrice(String type, double price) {if ("cloth".equals(type)) {if (price > 1000) {return price * 0.7;} else if (price > 800) {return price * 0.75;} else if (price > 600) {return price * 0.8;} else if (price > 500) {return price * 0.85;} else if (price > 300) {return price * 0.88;} else if (price > 200) {return price * 0.9;} else {return price;}} else if ("snacks".equals(type)) {if (price > 500) {return price * 0.8;} else if (price > 300) {return price * 0.85;} else if (price > 200) {return price * 0.88;} else {return price;}} else if ("vegetable".equals(type)) {if (price > 200) {return price * 0.8;} else if (price > 100) {return price * 0.88;} else if (price > 50) {return price * 0.95;} else {return price;}}return price;}

使用策略模式优化:

废话不多说,直接上代码

1、首先定义一个价格计算策略接口

public interface PriceCalculationStrategy {double calculatePrice(double price);
}

2、衣物价格计算策略实现类

public class ClothPriceCalculationStrategy implements PriceCalculationStrategy {@Overridepublic double calculatePrice(double price) {if (price > 1000) {return price * 0.7;} else if (price > 800) {return price * 0.75;} else if (price > 600) {return price * 0.8;} else if (price > 500) {return price * 0.85;} else if (price > 300) {return price * 0.88;} else if (price > 200) {return price * 0.9;} else {return price;}}
}

当然这里如果你不想使用大量的if-else,也可以使用Map,因为Map也是一种类似于策略模式的思想,这里的Map是在静态代码块进行属性设置的,优点如下:

  1. 采用空间换取时间的思想后,Map在程序启动之后即可预先赋值。当然不必担心内存溢出的问题,自JDK 8以后,方法区的实现类是元空间,其内存存在于实际内存中,而非JVM。因此,new几个对象占用的空间犹如沧海一粟;
  2. 可以把key, value像枚举一样一行行写出来,易于修改。

具体实现如下:

public class ClothPriceCalculationStrategy implements PriceCalculationStrategy {private static final Map<Integer, Double> DISCOUNT_MAP = new HashMap<>();static {DISCOUNT_MAP.put(1000, 0.7);DISCOUNT_MAP.put(800, 0.75);DISCOUNT_MAP.put(600, 0.8);DISCOUNT_MAP.put(500, 0.85);DISCOUNT_MAP.put(300, 0.88);DISCOUNT_MAP.put(200, 0.9);}@Overridepublic double calculatePrice(double price) {for (int threshold : DISCOUNT_MAP.keySet()) {if (price > threshold) {return price * DISCOUNT_MAP.get(threshold);}}return price;}
}

 3、零食价格计算策略实现类

public class SnacksPriceCalculationStrategy implements PriceCalculationStrategy {@Overridepublic double calculatePrice(double price) {if (price > 500) {return price * 0.8;} else if (price > 300) {return price * 0.85;} else if (price > 200) {return price * 0.88;} else {return price;}}
}

4、 蔬菜价格计算策略实现类

public class VegetablePriceCalculationStrategy implements PriceCalculationStrategy {@Overridepublic double calculatePrice(double price) {if (price > 200) {return price * 0.8;} else if (price > 100) {return price * 0.88;} else if (price > 50) {return price * 0.95;} else {return price;}}
}

5、测试,通过new不同的策略,传入价格即可计算。 

public class test {public static void main(String[] args) {// ---通过new不同的策略实现类进行计算价格---// 衣物类满减策略PriceCalculationStrategy clothPriceCalculationStrategy = new ClothPriceCalculationStrategy();System.out.println(clothPriceCalculationStrategy.calculatePrice(1738));// 食品类满减策略PriceCalculationStrategy snacksPriceCalculationStrategy = new SnacksPriceCalculationStrategy();System.out.println(snacksPriceCalculationStrategy.calculatePrice(375));// 蔬菜类满减策略PriceCalculationStrategy vegetablePriceCalculationStrategy = new VegetablePriceCalculationStrategy();System.out.println(vegetablePriceCalculationStrategy.calculatePrice(77));}
}

当然,我们可以使用工厂模式进一步优化

也就是通过工厂统一管理,直接new 一个工厂传参即可,直接上代码:

1、创建价格计算工厂策略类

public class PriceCalculationStrategyFactory {private static final Map<String, PriceCalculationStrategy> strategyMap = new HashMap<>();static {strategyMap.put("cloth", new ClothPriceCalculationStrategy());strategyMap.put("snacks", new SnacksPriceCalculationStrategy());strategyMap.put("vegetable", new VegetablePriceCalculationStrategy());}public double calculatePrice(String type, double price) {PriceCalculationStrategy strategy = strategyMap.get(type);if (strategy != null) {return strategy.calculatePrice(price);}return price;}
}

 2、测试,通过new一个工厂,传入类型和价格即可。 

public class test {public static void main(String[] args) {PriceCalculationStrategyFactory factory = new PriceCalculationStrategyFactory();double cloth = factory.calculatePrice("cloth", 1738);double snacks = factory.calculatePrice("snacks", 375);double vegetable = factory.calculatePrice("vegetable", 77);System.out.println("满减计算后,衣服价格:" + cloth);System.out.println("满减计算后,零食价格:" + snacks);System.out.println("满减计算后,蔬菜价格:" + vegetable);}
}

总结

  1. 对于大量的if-else,特别是大量的嵌套的if-else,可以用策略模式+工厂模式优化,少量的if-else就没必要了;
  2. 使用设计模式,将会增加代码量,但是解耦性特别强,代码更加清晰易懂,而且具有更强的扩展性和维护性。
  3. 策略模式将不同的责任分配到不同的类中,实现单一职责原则,提高代码的内聚性。

ps:以下是我整理的java面试资料,感兴趣的可以看看。最后,创作不易,觉得写得不错的可以点点关注!

链接:https://www.yuque.com/u39298356/uu4hxh?# 《Java面试宝典》 

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Mybatis DAO开发

使用Mybatis开发Dao&#xff0c;通常有两个方法&#xff0c;即 原始Dao开发方法Mapper代理开发方法 原始DAO开发方式 原始Dao开发方法需要程序员编写Dao接口和Dao实现类&#xff0c;无非就是在Dao实现类里面调用映射文件里面定义的sql而已。 工具类 package org.example.u…

海康威视-AIOT的业务转型

海康威视的转型和定位为智能物联网&#xff08;AIoT&#xff09;解决方案和大数据服务的提供商。 公司不仅仅聚焦于其核心的视频监控业务&#xff0c;而且正在积极拓展到新的技术领域和市场。通过专注于物联感知、人工智能、大数据等技术的创新&#xff0c;对未来技术发展方向的…

ptx指令,抽象指令与架构

&#xff08;没用的问题&#xff1a;ptx如何抽象sass&#xff0c;它创造ir的方式和结果与mlir 创造ir有什么区别吗&#xff1f;&#xff09; PTX操作数类型&#xff1a; 寄存器操作数&#xff1a;在PTX中&#xff0c;寄存器用于存储临时数据&#xff0c;并在指令之间传递值。寄…

生产计划数据模型,实现能源企业数字化高效管理

随着市场经济的快速发展&#xff0c;能源企业在经济发展中的地位也随之提高。但由于能源企业在生产计划经济管理上存在指标不平衡、市场观念落后和环保意识欠缺等问题&#xff0c;导致企业的经济效益降低。目前&#xff0c;提高企业的生产计划管理是改善能源企业现状最有利的途…

计算机网络:物理层下的传输媒体概览

✨✨ 欢迎大家来访Srlua的博文&#xff08;づ&#xffe3;3&#xffe3;&#xff09;づ╭❤&#xff5e;✨✨ &#x1f31f;&#x1f31f; 欢迎各位亲爱的读者&#xff0c;感谢你们抽出宝贵的时间来阅读我的文章。 我是Srlua小谢&#xff0c;在这里我会分享我的知识和经验。&am…

MySQL---视图

目录 一、介绍 二、语法 三、视图的更新 四、视图作用 一、介绍 视图&#xff08;View&#xff09;是一种虚拟存在的表。视图中的数据并不在数据库中实际存在&#xff0c;行和列数据来自定义视图的查询中使用的表&#xff0c;并且是在使用视图时动态生成的。 通俗的讲&#…

Git常用指令总结

Git常用指令总结 下载git&#xff0c;这个不需要交的&#xff01;&#xff01;&#xff01; 1、初始化自己的git仓库 git config --global user.name “Your name” 配置自己的用户名 git config --global user.email “mailexample.com” 配置邮箱 git config --global c…

blender记一下法线烘焙

这里主要记一下使用cage的方式 原理 看起来是从cage发射射线&#xff0c;打中高模了就把对应uv那个地方的rgb改成打中的点的normal的rgb 正事 那么首先需要一个高模 主要是几何要丰富 无所谓UV 然后一个低模&#xff0c;既然上面提到UV&#xff0c;那低模就要展UV, 展完之后…

Ambari——编译——解决解决windows和linux下phantomjs链接超时问题

您的支持是我继续创作与分享的动力源泉!!! 您的支持是我继续创作与分享的动力源泉!!! 您的支持是我继续创作与分享的动力源泉!!! 错误日志: [INFO] Copying extracted folder C:\Users\LENOVO\AppData\Local\Temp\phantomjs\phantomjs-2.1.1-windows.zip-extract-1786692…

『K8S 入门』三:资源调度

『K8S 入门』三&#xff1a;资源调度 一、Label 和 Selector 可以通过 Selector 基于 Label 匹配需要的资源 Label 标签 配置文件中&#xff08;metadata.labels&#xff09;配置 metadata: # Pod相关的元数据&#xff0c;用于描述Pod的数据name: nginx-demo #Pod的名称lab…

后端Jwt实现Token编码、解码以及axios的request请求头的Token传输方式

目录 一、什么是JWT&#xff1a; 二、Jwt的使用&#xff1a; 第一步&#xff1a;引入依赖&#xff1a; 第二步&#xff1a;配置拦截器&#xff1a;JwtInterceptor.java&#xff1a; 其中异常文件ServiceException配置如下&#xff1a; 全局异常文件GlobalException.java文…

利用Base64加密算法将数据加密解密

1. Base64加密算法 Base64准确来说并不像是一种加密算法&#xff0c;而更像是一种编码标准。 我们知道现在最为流行的编码标准就是ASCLL&#xff0c;它用八个二进制位&#xff08;一个char的大小&#xff09;表示了127个字符&#xff0c;任何二进制序列都可以用这127个字符表…

hbuilderX打包vue项目白屏问题以及element-ui的icon图标无法正常显示问题

附录一&#xff1a;hbuilderX打包vue项目白屏问题 将项目目录下的config文件夹里的index.js文件中,将build对象下的assetsPublicPath中的“/”&#xff0c;改为“./”后&#xff0c;再打包生成的 dist 文件 build: { // assetsPublicPath: /,//修改前 assetsPublicPa…

逻辑 | 逻辑先修营

学习到更新日期逻辑先修营-3常见逻辑连词及逻辑表达2024-3-23 1.形式逻辑基础1 2.形式逻辑基础2 3.常见逻辑连词及逻辑表述 4.OR相关考点 5.AND相关考点 6.逻辑箭头基本考点1 7.逻辑箭头基本考点2 8.代入逻辑推理事实真1 9.代入逻辑推理事实真2 10.形式逻辑四大基本考点…

C语言-指针问题-排序问题

题目描述 输入 10 个整数&#xff0c;将他们从小到大排序后输出&#xff0c;并给出每个元素在原来序列中的位置. 将程序需要的代码补全&#xff0c;只提交 begin 到 end 部分的代码。 #include <stdio.h> #define N 10int main() {int a[N], b[N], cnt 1, i, j, tmp;…

【Entity Framework】 EF中DbContext类详解

【Entity Framework】 EF中DbContext类详解 一、概述 DbContext类是实体框架的重要组成部分。它是应用域或实例类与数据库交互的桥梁。 从上图可以看出DbContext是负责与数据交互作为对象的主要类。DbContext负责以下活动&#xff1a; EntitySet&#xff1a;DbContext包含…

Web前端—事件循环

事件循环 事件循环浏览器的进程模型何为进程&#xff1f;何为线程&#xff1f;浏览器有哪些进程和线程&#xff1f; 渲染主线程是如何工作的&#xff1f;若干解释何为异步&#xff1f;面试题&#xff1a;如何理解JS的异步&#xff1f;JS会阻碍渲染任务有优先级吗&#xff1f;面…

宜搭低代码高级认证实操题2 faas连接器加密解密

密钥维护页-保证有一条数据 敏感信息提交页 存档页&#xff0c;只是用来存数据的审批的时候不用这个表提交数据不然会出两条 授权查看页 FaaS连接器先下载好他的示例代码然后按照要求配置好参数直接拷贝进去就行 然后需要在云开发环境里面先new一个terminal然后跑一下./builde…

Leetcode - 周赛389

目录 一&#xff0c;3083. 字符串及其反转中是否存在同一子字符串 二&#xff0c;3084. 统计以给定字符开头和结尾的子字符串总数 三&#xff0c;3085. 成为 K 特殊字符串需要删除的最少字符数 四&#xff0c;3086. 拾起 K 个 1 需要的最少行动次数 一&#xff0c;3083. 字符…

3月23日,每日信息差

&#x1f396; 素材来源官方媒体/网络新闻 &#x1f384; 首个国产单池万卡液冷算力集群投入运营&#xff0c;满足万亿级大模型训练需求 &#x1f30d; 快手电商正式启动兴农计划 &#x1f30b; 360AI浏览器APP即将上线&#xff0c;支持500万字长文本处理 &#x1f381; 安卓 1…