聊一聊代码重构——封装集合和替换算法的代码实践
代码重构相关内容
聊一聊代码重构——我们为什么要代码重构
聊一聊代码重构——代码中究竟存在哪些坏代码
聊一聊代码重构——关于变量的代码实践
聊一聊代码重构——关于循环逻辑的代码实践
聊一聊代码重构——关于条件表达式的代码实践
聊一聊代码重构——程序方法上的代码实践
聊一聊代码重构——程序方法和类上的代码实践
聊一聊代码重构——存在继承关系类上的代码实践
聊一聊代码重构——封装集合和替换算法的代码实践
封装集合
对集合属性进行封装
很多时候我们封装了对象属性的访问,这能提供属性的安全性,但是对于集合,我们一般会将集合作为一个整体来控制。这使得我们可以直接访问并修改集合,这使得集合变得脆弱。而很多时候我们更加在意的是集合内部的元素的操作,而不是对集合本身进行修改。所以在对象存在集合属性时,需要对集合进行特殊的封装。
需要那些封装
- 在getter方法中,返回集合的一个只读拷贝,以防止外部代码修改集合。
- 在setter方法中,进控制,将对集合的修改限制在元素上的修改。
- 对集合添加对集合元素内操作的方法。
就像下面对属性的封装
public class ShoppingCart {private List<Item> items = new ArrayList<>();public void addItem(Item item) {items.add(item);}public void removeItem(Item item) {items.remove(item);}public double getTotalPrice() {double total = 0;for (Item item : getItems()) {total += item.getPrice();}return total;}public List<Item> getItems() {return Collections.unmodifiableList(items);}private void setItems(List<Item> items) {this.items = items;}
}
在上面的示例中,我们将 items 属性设置为私有,并创建了 getter 和 setter 方法。我们在 setter 方法中添加了一些逻辑,以确保集合只能通过该方法进行修改。在 getter 方法中,我们返回集合的一个只读拷贝,以防止外部代码修改集合。在 getTotalPrice 方法中,我们通过 getItems 方法来访问集合。最终,我们可以逐步修改代码中所有直接访问 items 属性的地方,使其改为通过 getter 和 setter 方法进行访问。
替换算法
很多时候在最开始实现业务的时候对业务最终展现的形式不是很清晰,或者因为时间原因我们只能选择最快实现业务的方式。但是这些内容有可能并不是最好的方式,在原先的做法之外,可能存在更简单的解决方案,此时在重构代码时需要尝试对原来算法进行重构。比如使用更高效的算法替代低效算法,使用已经存在的三方库中方法替代自己编写的方法等。
如何进行算法替换
- 选择一个可以替换当前算法的新算法。
- 如果新的算法不是三方库中已有的内容,则将新算法实现为一个新的方法。
- 在原方法调用地方切换为新方法。
- 测试正确性,比较新算法的性能。
什么样的内容要替换算法
-
使用高效算法替换低效的算法
-
使用高可读性的算法替换低可读性算法
引入特例
特殊的逻辑
正常业务中,即使逻辑分支不同,但是其需要经历的流程大多是类似的,这个时候我们使用一些系列公共逻辑将其抽象。后来的开发同学在理解这些内容时会更加容易。但是某些时候,总会有某个特殊的逻辑分支在业务逻辑或者涉及数据范围都和其他分支差异巨大。为了不破坏原有代码结构和设计,又不想在父类中添加太多的特定逻辑。我们可以声明一个特殊标记的专门类来处理这个逻辑,需要处理这个逻辑的地方调用这个特例类的方法。这个特例类通常是一个继承自父类的子类,但是只包含特定的逻辑处理,不包含其他的业务逻辑。这样既完成了特殊处理,又保持原有的代码结构和设计,避免对原有代码的影响和破坏。但是,过度使用引入特例可能会导致代码过于复杂和难以维护,因此需要根据具体情况进行选择和使用。
下面情况下可以考虑使用引入特例的重构
-
如果业务分支中,存在大量针对特殊情况的判断和处理,并且这些特殊情况的处理逻辑相同。
-
特殊分支处理逻辑和正常情况的处理逻辑内容迥异,其逻辑会影响对正常逻辑的理解和扩展。
尝试引入特例的
- 审查代码,找出代码中符合上面描述的特殊情况。
- 创建一个特例类,该类应该继承自原来的类,并重写特殊情况下的方法。
- 在原来的类中添加一个方法,用于判断当前是否为特殊情况。
- 在原来的类中,将特殊情况下的代码替换为使用特例类的代码。如果当前为特殊情况,则创建特例类的实例并调用其方法,否则调用原来的方法。
- 测试
下面是一个使用特例方式重构的demo
原始代码中getTotalPrice(),当检测到特殊产品ID时候会使用与正常计算规则不同的计算方式。如果一个系统中是通过优惠标记来进行产品折扣的,那么这种固定产品ID进行折扣的方式,显然和产品正常涉及的逻辑不相符合。这个时候我们可以提供一个特殊的对象,将其内部处理逻辑和正常逻辑隔离出来
public class Order {private int productId;private int quantity;private double price;public Order(int productId, int quantity, double price) {this.productId = productId;this.quantity = quantity;this.price = price;}public double getTotalPrice() {if (productId == 1) {return quantity * price * 0.9;} else {return quantity * price;}}
}
在下面新建一个继承于新对象的SpecialPriceOrder,初始化时使用新的对象取代原始对象。将正常的代码逻辑和特殊的代码逻辑隔离出来
public class SpecialPriceOrder extends Order {public SpecialPriceOrder(int productId, int quantity, double price) {super(productId, quantity, price);}@Overridepublic double getTotalPrice() {return super.getTotalPrice() * 0.9;}
}public class Order {private int productId;private int quantity;private double price;public Order(int productId, int quantity, double price) {this.productId = productId;this.quantity = quantity;this.price = price;if (productId == 1) {this.setSpecialOrder(new SpecialPriceOrder(productId, quantity, price));}}......
}
相关文章:
聊一聊代码重构——封装集合和替换算法的代码实践
代码重构相关内容 聊一聊代码重构——我们为什么要代码重构 聊一聊代码重构——代码中究竟存在哪些坏代码 聊一聊代码重构——关于变量的代码实践 聊一聊代码重构——关于循环逻辑的代码实践 聊一聊代码重构——关于条件表达式的代码实践 聊一聊代码重构——程序方法上的…...
FPGA解码4K分辨率4line MIPI视频 OV13850采集 提供工程源码和技术支持
目录1、前言2、Xilinx官方主推的MIPI解码方案3、纯Vhdl方案解码MIPI4、vivado工程介绍5、上板调试验证6、福利:工程代码的获取1、前言 FPGA图像采集领域目前协议最复杂、技术难度最高的应该就是MIPI协议了,MIPI解码难度之高,令无数英雄竞折腰…...
Map接口及遍历方式
1、Map接口实现类的特点1)Map与Collection并列存在。用于保存具有映射关系的数据:Key-Value(无序)2) Map中的key和value可以是任何引用类型的数据,会封装到HashMap$Node对象中3) Map 中的key不允许重复import java.util.HashMap; import java…...
一步步构建自己的前端项目
一、我们先把webpack走通 1、先安装相关依赖,webpack是用来处理命令行参数的,但是我不准备使用webpack-cli,但是还是要求必须安装webpack-cli npm install webapck webpack-cli --save-dev2、npm init -y 3、创建项目结构 build.js cons…...
VMware搭建Mac OS环境
推荐阅读 Proxifier逆向分析(Mac) MacOS Burp2021安装配置 突破iOS App双向认证抓包 App绕过iOS手机的越狱检测 iOS系统抓包入门实践之短链 各种学习环境更新MacOS虚拟机 Android和iOS静态代码扫描工具 iOS系统抓包之短链-破解双向证书 Android和iOS应用源码的静态分析…...
【Maven】什么是Maven?Maven有什么用?
目录 一、什么是 Maven 二、Maven 能解决什么问题 三、Maven 的优势举例 四、Maven 的两个经典作用 4.1 Maven 的依赖管理 4. 2 项目的一键构建 💟 创作不易,不妨点赞💚评论❤️收藏💙一下 一、什么是 Maven Maven 的正确发…...
【JavaSE】类和对象的详解
前言: 大家好,我还是那个不会打拳的程序猿。今天我给大家讲解的是类和对象,相信大家在之前的学习中都是面向过程的思想,那么今天就让我们走向面向对象的世界吧。 目录 1.面向过程VS面向对象 1.1什么是面向过程 1.2什么是面向对…...
2023年中职组“网络安全”赛项广西自治区竞赛任务书
2023年中职组“网络安全”赛项 广西自治区竞赛任务书 一、竞赛时间 总计:360分钟 需求环境可私信博主!点个赞加三连吧! 二、竞赛阶段 竞赛阶段 任务阶段 竞赛任务 竞赛时间 分值 A、B模块 A-1 登录安全加固 180分钟 200分 A-2…...
简单的自定义录屏工具
在csdn上写文章,需要配一些操作动态图,需要针对电脑录屏,可能是整个屏幕录屏,也可能是某窗口,甚至是某一小块区域。 动态图最好是gif格式,方便直接嵌入文章中。 一、设计 窗口类widget 切屏类Capturescr…...
数据结构与算法基础(王卓)(17):KMP算法详解(精讲(最简单、直接、有效的思路方法,答案以及代码原理)
本文具体思路参考: (最后证明,该教材/网课实际上是最有效的) DS第四章【3】KMP1_哔哩哔哩_bilibili 中间走的一些弯路的教材: 第06周05--第4章串、数组和广义表5-4.3串的操作--串的匹配算法2--KMP算法_哔哩哔哩_bi…...
【java基础】HashMap源码解析
文章目录基础说明构造器put方法(无扩容,无冲突)put方法(无冲突,有扩容)put方法(有冲突,无树化)put方法(有冲突,树化)remove方法&#…...
实现异步的8种方式,你知道几个?
一、前言 在编程中,有时候我们需要处理一些费时的操作,比如网络请求、文件读写、数据库操作等等,这些操作会阻塞线程,等待结果返回。为了避免阻塞线程、提高程序的并发处理能力,我们常常采用异步编程。 异步编程是一种…...
二叉树的三种遍历
二叉树的遍历可以有:先序遍历、中序遍历、后序遍历先序遍历:根、左子树,右子树中序遍历:左子树、根、右子树后序遍历:左子树、右子树、根下面是我画图理解三种遍历:二叉树里都是分为左子树和右子树。分治思…...
我,30岁程序员被裁了,千万别干全栈
大家好,这里是程序员晚枫,今天是读者投稿。下面开始我们的正文。👇 关注博主👉程序员晚枫 很久了,今天给大家分享一下我从事程序员后,30岁被裁的经历,希望帮到有需要的人。 1、我被裁了 大家好…...
【linux】:进程地址空间
文章目录 前言一、进程地址空间总结前言 本篇文章接着上一篇文章继续讲解进程,主要讲述了进程在运行过程中是如何在内存中被读取的以及为什么要有虚拟地址的存在,CPU在运行过程中是拿到程序的虚拟地址还是真实的物理内存。 一、进程地址空间 下面我们先…...
【保姆级】JMeter Mqtt 压测配置
忽然有个紧急任务要对某个服务做MQTT做压测,紧急实操下JMeter,这里记录下非专业测试员的测试过程、(▽`),欢迎👏大家检查指点( ̄∇ ̄)/下载⏬工具JMeter官方下载地址https://jmeter.apache.org/do…...
C语言数据结构初阶(4)----带头双向循环链表
我们先来看看带头双向循环链表的结构:看到这里我们可能会产生一个想法:这个链表看起来好复杂的样子,是不是它的增删改查比单链表更难写呢?嘿嘿,还真的不是这样的,双向链表的增删改查是很好写的哦࿰…...
原生javascript手写一个丝滑的轮播图
通过本文,你将学到: htmlcssjs 没错,就是html,css,js,现在是框架盛行的时代,所以很少会有人在意原生三件套,通过本文实现一个丝滑的轮播图,带你重温html,css和js基础知识。 为什么选用轮播图做示例&…...
【Linux】进程优先级(进程优先级 Linux下优先级 用top命令更改已存在进程的nice 其他概念 进程切换)
文章目录进程优先级Linux下优先级用top命令更改已存在进程的nice:其他概念进程切换进程优先级 我们作为使用者一般不关心优先级,它跟我们的调度器有很大的关系,调度器是为了跟均衡的调度进程。 什么叫做优先级? 优先级和权限是两…...
2016年chatGPT之父Altman与马斯克的深度对话(值得一看)
2016年9月,现今OpenAI CEO,ChatGPT之父,时任创投公司Y Combinator的总裁Sam Altman在特斯拉加州弗里蒙特工厂采访了埃隆马斯克。马斯克阐述了创建OpenAI的初衷,以及就他而言,对于未来最为重要的五件事。这是OpenAI的两…...
Day131 | 灵神 | 回溯算法 | 子集型 子集
Day131 | 灵神 | 回溯算法 | 子集型 子集 78.子集 78. 子集 - 力扣(LeetCode) 思路: 笔者写过很多次这道题了,不想写题解了,大家看灵神讲解吧 回溯算法套路①子集型回溯【基础算法精讲 14】_哔哩哔哩_bilibili 完…...
无法与IP建立连接,未能下载VSCode服务器
如题,在远程连接服务器的时候突然遇到了这个提示。 查阅了一圈,发现是VSCode版本自动更新惹的祸!!! 在VSCode的帮助->关于这里发现前几天VSCode自动更新了,我的版本号变成了1.100.3 才导致了远程连接出…...
蓝桥杯 2024 15届国赛 A组 儿童节快乐
P10576 [蓝桥杯 2024 国 A] 儿童节快乐 题目描述 五彩斑斓的气球在蓝天下悠然飘荡,轻快的音乐在耳边持续回荡,小朋友们手牵着手一同畅快欢笑。在这样一片安乐祥和的氛围下,六一来了。 今天是六一儿童节,小蓝老师为了让大家在节…...
Java 加密常用的各种算法及其选择
在数字化时代,数据安全至关重要,Java 作为广泛应用的编程语言,提供了丰富的加密算法来保障数据的保密性、完整性和真实性。了解这些常用加密算法及其适用场景,有助于开发者在不同的业务需求中做出正确的选择。 一、对称加密算法…...
多模态大语言模型arxiv论文略读(108)
CROME: Cross-Modal Adapters for Efficient Multimodal LLM ➡️ 论文标题:CROME: Cross-Modal Adapters for Efficient Multimodal LLM ➡️ 论文作者:Sayna Ebrahimi, Sercan O. Arik, Tejas Nama, Tomas Pfister ➡️ 研究机构: Google Cloud AI Re…...
高防服务器能够抵御哪些网络攻击呢?
高防服务器作为一种有着高度防御能力的服务器,可以帮助网站应对分布式拒绝服务攻击,有效识别和清理一些恶意的网络流量,为用户提供安全且稳定的网络环境,那么,高防服务器一般都可以抵御哪些网络攻击呢?下面…...
如何理解 IP 数据报中的 TTL?
目录 前言理解 前言 面试灵魂一问:说说对 IP 数据报中 TTL 的理解?我们都知道,IP 数据报由首部和数据两部分组成,首部又分为两部分:固定部分和可变部分,共占 20 字节,而即将讨论的 TTL 就位于首…...
AI病理诊断七剑下天山,医疗未来触手可及
一、病理诊断困局:刀尖上的医学艺术 1.1 金标准背后的隐痛 病理诊断被誉为"诊断的诊断",医生需通过显微镜观察组织切片,在细胞迷宫中捕捉癌变信号。某省病理质控报告显示,基层医院误诊率达12%-15%,专家会诊…...
【分享】推荐一些办公小工具
1、PDF 在线转换 https://smallpdf.com/cn/pdf-tools 推荐理由:大部分的转换软件需要收费,要么功能不齐全,而开会员又用不了几次浪费钱,借用别人的又不安全。 这个网站它不需要登录或下载安装。而且提供的免费功能就能满足日常…...
[ACTF2020 新生赛]Include 1(php://filter伪协议)
题目 做法 启动靶机,点进去 点进去 查看URL,有 ?fileflag.php说明存在文件包含,原理是php://filter 协议 当它与包含函数结合时,php://filter流会被当作php文件执行。 用php://filter加编码,能让PHP把文件内容…...
