重构

重构

参数过长

影响:

方法不易被理解、使用,方法签名容易不稳定,不易维护

解决方法:反复使用提炼方法+内联方法,消除多余参数

​ 尽量把方法移进相关的类中

​ 如实体类中的get方法在其他类中没有被调用可以删除

​ 实际工作中,可以结合参数数量、以及自身对业务的理解,在 最小知道 和 保持对象完整性 之间进行权衡

全局变量

影响:可以在任何位置进行修改,在使用过程中可能出现意想不到的值,并且没有任何机制可以探测出哪段代码进行了修改,导致定位困难

改进目标:

降低代码耦合性,保持代码清晰,维护简单,降低由于对全局数据随意的改变引发bug的风险

方法:封装变量,提炼函数

使用Convert To Instance Method替换项目中使用静态方法的地方,进行重构

如果想避免其他类中引用本类的字段,修饰符改为private

可变数据

影响:

影响可维护性,在一处修改数据,却在另一处造成难以发现的破坏
改进目标:

应用”数据不可变”:不可变性是强大的代码防腐剂
方法:
封装变量、拆分变量、提炼函数、移除设值,函数、查询取代派生、Builder模式创建不可变对象、引用对象改为值对象、函数式编程等

发散式变化

定义:
某个模块经常因为不同的原因在不同的方向上发生变化
影响:
通常,发散式变化是由于多个变化方向之间有较多的来回调用或者函数内部混合了多类处理逻辑。当处于多个不同上下文的外部行为发生变化时候,都会引起对同一个类或模块的修改,影响了代码的可读和可维护性
改进目标:
提高代码组织结构、职责单一提升代码可读性、可维护性
方法:
拆分阶段
搬移函数
提炼函数
提炼类

霰弹式修改

定义:

霰弹式修改:指的是如果每遇到某种变化,你都必须在许多不同的类内做出许多小修改。此时,你所面临的坏味道就是霰弹式修改

影响:

修改的地方四面散布,而且有可能修改之后导致其他异常结果

改进目标:

更好的代码组织,更少的代码重复

方法:
搬移函数、搬移字段、函数组合成类、函数组合成变换、拆分阶段、内联函数、内联类

clone的应用

这里之所以使用 clone,是因为在跨边界调用场景下,直接更改原对象会有一定风险。
比如某些场景下,边界外更改对象可能改变边界内状态,或者调用方想维护多个状态时可能引发混乱。
因此一般涉及状态信息更新时,尽量不直接处理同一对象(使用clone),或不暴露完整对象(返回部分需要的属性)。
如果需要内部维护对象状态,又需要将完整对象暴露出去,就返回一个副本(比如当前案例,如果 clonePaySlip 需要在内部缓存,那么返回值应当进一步优化为:clonePaySlip.clone())

依恋情节

定义:
依恋情节/特性依恋:一个函数跟另一个模块中的函数或数据交流格外频繁,远胜于在自己所处模块内部的交流
影响:
可读性、可维护性低:调用另一模块功能时往往需要打一套组合拳才能完成,需要知道过多的细节;往往会伴随有”内幕交易、重复代码、霰弹式修改……”
改进目标
将函数搬移到对应的类,解除跨模块的过多交流
方法
提炼函数、搬移函数
注:策略模式、访问者模式往往会带来依恋情节,这不是说这两个模式不可取。我们需要理解:
从根本上来说,我们消除”依恋情节”和应用这些设计模式都是为了把一起变化的东西放到一块儿

——《重构,改善既有代码的设计》

数据泥团

定义
总是成块出现的相同数据项,包括多个类中相同的字段、多个方法签名中相同的参数等
影响
成块出现的重复参数过多,影响阅读和理解,难维护
改进目标
减少相同的字段及入参,缩短入参列,简化函数调用
方法
提炼类 引入参数对象 保持对象完整性

Tip:内联

这里之所以能够直接内联,是因为字段是final的,只会读取,不会更新,大家可以尝试在非final上内联,IDEA会提示我们内联失败。因此当我们需要通过内联的方法消除字段时,需要先想办法把字段变为final的

Ctrl+Alt+N

重构

Original: https://www.cnblogs.com/zz01/p/16488060.html
Author: 山野村夫01
Title: 重构

原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/586978/

转载文章受原作者版权保护。转载请注明原作者出处!

(0)

大家都在看

  • 使用mybatis-generator生成的mapper执行insert时获取主键id

    有时候,我们在往mysql数据库插入一行数据的同时,想要知道这一行数据的主键id。mybatis提供了2种获取自增主键的方式:一种是,另一种是使用这三个属性: useGenerat…

    Java 2023年5月30日
    063
  • 前端,单个文件下载或者分批压缩多个文件下载

    import JSZip from "jszip"; import fileSaver from "file-saver"; import …

    Java 2023年6月8日
    078
  • 多线程与高并发(四)—— 根据 HotSpot 源码讲透 Java 中断机制

    前言 我们首先介绍中断的三个 APPI 及其底层代码,在对方法的实现有了清晰的认知后,再结合场景谈谈什么是中断,以及中断该如何正确使用? 一、中断方法 1. isInterrupt…

    Java 2023年6月9日
    050
  • LocalDateTime接收前端String格式

    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") private LocalDateTime createTime; 实…

    Java 2023年6月6日
    092
  • 前后端分离结构中使用shiro进行权限控制

    前阵子在前后端分离项目中集成shiro项目,折腾了一下子,参考了网上一些博客,发现大多都还是之前传统的模式,并不适用于前后端分离结构。今天抽空整理了下demo,方便以后使用以及后来…

    Java 2023年6月5日
    084
  • 泛型的类型擦除后,fastjson反序列化时如何还原?

    原创:微信公众号 码农参上,欢迎分享,转载请保留出处。 哈喽大家好啊,我是Hydra~ 在前…

    Java 2023年6月5日
    096
  • Centos7安装Docker

    0.安装Docker Docker 分为 CE 和 EE 两大版本。CE 即社区版(免费,支持周期 7 个月),EE 即企业版,强调安全,付费使用,支持周期 24 个月。 Dock…

    Java 2023年6月13日
    079
  • C/C++取模为什么和数学中的不同

    C/C++ 中的取模运算和数学中有什么不同 C/C++/Java 的取模运算和数学中有些不同,一定要注意!!! 先举一个简单的例子: -1 % 3 = ? 而对于这个例子,不同的程…

    Java 2023年6月5日
    087
  • 拒绝蛮力,高效查看Linux日志文件!

    原创:扣钉日记(微信公众号ID:codelogs),欢迎分享,转载请保留出处。 简介 日常分析问题时,会频繁地查看分析日志,但如果蛮力去查看日志,耗时费力还不一定有效果,因此我总结…

    Java 2023年6月7日
    0109
  • Docker的常用基本命令

    基本命令 官网:https://docs.docker.com/engine/reference/commandline/docker/ 查看容器CPU状态 docker stat…

    Java 2023年6月5日
    069
  • 宿舍管理系统——单链表+结构体实现入住、退房和查询功能(C语言版)

    本程序的编译和运行环境如下(如果有运行方面的问题欢迎在评论区留言,也欢迎直接加QQ:2961439733,备注博客园或CSDN即可): 编辑工具:Dev-C++(版本:5.11.0…

    Java 2023年6月8日
    087
  • 大三上 期中考试

    湛江师范学院 2014 - 2015 学年度第 1 学期 期中试卷 科目:LINUX 平台及应用 C 编程 shell编程 100 蔡广基 评卷人 蔡广基 一、操作题。添加一个 1…

    Java 2023年6月13日
    077
  • java基础-集合

    以下为本人的学习笔记 1.集合框架概述 1.1集合框架 的作用 在实际开发中,我们经常会对一组相同类型的数据进行统一管理操作。到目前为止,我们可以使用数组结构,链表结构,二叉树来实…

    Java 2023年6月15日
    0101
  • Sharepoint 2013 系列篇(安装部署)–上篇

    前言 sharepoint的部署是按照物理拓扑图的架构来部署,按照物理拓扑图架构分为一层拓扑图架构,二层拓扑图架构,三层拓扑图架构,多层拓扑图架构。 按照分层的拓扑图部署是按照需求…

    Java 2023年6月7日
    099
  • 为大势趋,驭势者胜:引迈信息三周年回顾与展望

    三年的风雨兼程,三年的创新研发,自福建引迈信息技术有限公司成立以来,始终坚持以创新为引领发展的第一动力,坚持”以客户为中心,以产品为导向”的发展理念,不断进…

    Java 2023年6月5日
    077
  • 类与对象(二)

    将对象用作参数 任何数据类型其实都可以作为参数传递给方法; 如果是引用类型的变量作为参数传递,就是对象传递(本质是对象的地址传递) 参数的引用传递 方法调用时传参,本质上都是将实参…

    Java 2023年6月6日
    077
亲爱的 Coder【最近整理,可免费获取】👉 最新必读书单  | 👏 面试题下载  | 🌎 免费的AI知识星球