首页 > 其他分享 >24种常见的坏味道及重构手法

24种常见的坏味道及重构手法

时间:2023-04-10 20:00:14浏览次数:33  
标签:24 重构 里面 数据 味道 方法 修改 比如 属性

  1. 神秘命名
    • 不能见名知意
    • 尽量去一个合适的名字
  2. 重复代码
    • 改动的时候很必须要全部找出,修改困难
    • 抽取公共代码,以便统一维护
  3. 过长的函数
    • 小读完所有行才知道清楚这个函数的大意,很多时候只需要知道这里面大概做了啥,不需要知道没一行做了啥,没行都读效率影响阅读效率,一般不要超过80行
    • 分段提取子方法
  4. 过长参数列表
    • 不便阅读,一般不要超过4个参数
    • 封装参数对象
  5. 过长的消息链
    • 类似于a.b.c.d.e这种
    • 在一个外观类里面提供一个xxE的方法,隐藏复杂的调用逻辑,后面a 只用和 这个外观类交互
  6. 全局数据
    • 容易被别人错误修改
    • 能不全局就不要全局,访问也小越好,如果有全局访问/修改的需求,可以考虑把这份数据放到对象的属性,然后通过对外提供方访问和修改。
  7. 可变数据
    • 址传递的时候,容易被别人误修改
    • 可以考虑不可变对象,final 关键字修饰,如果是构造参数可以考虑构造器模式
    • 全局数据和可变数据的都容易本别人修改,从而出问题,全局数据还有暴露信息太多的风险
  8. 发散式变化
    • 多种原因,都会修改同一段代码
    • 把多种变化的部分独立出来
  9. 霰弹式修改
    • 修改有一份功能,可能在很多份文件做小的调整
    • 可考虑把这些调整集中起来放到一个中介类里面管理
  10. 依恋情节
  • 类A的数据对类B的依赖比对类A还要高,比如汽车的动力只和发动机的型号有关,和汽车关系不大,所以马力应该 汽车.get发动机.get马力 而不是 汽车.get马力方法判断发动机型号)
  • 这时候我们应该考虑类A的这份数据是否可以放到类B去维护
  1. 泥团数据

    • 有时候两份数据是前关联的,其中一个出问题另一份数据就无法使用比如,地址的省市区,比如长方体的长宽高
    • 这种强关联的数据,最好提炼成为一个对象,而不是单独成为多个字段。
  2. 基本类型偏执

    • 比如坐标可以记作"x,y",但是坐标可能很多很多时候会拿到单独和横纵坐标x和y,也有可能需要格式化成(x,y)。比如金额5毛,可能需要显示成元,可能需要显示后面的货币符号。
    • 有具体含义,并且可能有其他伴生属性的对象,应该考虑封装成对象。
    • 可泥团数据类似,泥团数据强调多属性之间的依赖,基本数据偏执强调自身值的一些特性之间可能用对象表示更好,还可以隐藏细节。
  3. 重复的switch

    • 判断太多,不容易阅读,而且可能会写的很长
    • 使用策略,状态模式优化分支语句,把对应的逻辑写到各自的类里面去
  4. 简单的循环语句

    • 循环遍历,然后做一些简单的操作(过滤,分组,提取id,装换成别的对象,装换成Hash结构等)
    • 使用stream+lamda表达式可以很容易简洁的做到
  5. 冗赘的元素

    • 过度拆分的代码,比如一个一个日期格式工具,上面套了好几层,比如一个方法里面只要一行简单的方法调用。比如一段初始版本的计算现在已经完全弃用,比如已经注释的代码。这些东西都应该删除。
    • 这里更多是因为重构或者别的原因,导致其中一些方法已经失去原有的意义
  6. 夸夸其谈通用性

    • 和冗赘的元素元素类似,都是为了应对癔想的变化 过度封装,过度设计,写了很多结构复杂,预留拓展,实际可能几年了都没用上。
    • 这里强调过度设计的无效拓展性结构
  7. 临时字段

    • 大多是时候我们都会按照别的逻辑处理,但是有些特殊的情况,要在代码很多位置兼容这个特殊值
    • 我们可以考虑主服务程里面只写正常流程,特殊流程用另外一个特殊流程策略来处理,而不是把两者揉在一起。
  8. (过度使用)中间人

    • 如果a的方法里面存在大量直接简单包装调用a.b这种情况(超过一半,或者数量很多)
    • 这种时候应该提供getB,然后直接操作b,而不是总是在a里面去大量的包b的方法(如果少量这样干隐藏细节让人觉察不到b的存在是合理的)。
  9. 内幕交易

    • 和中间人相反,如果在a中直接返回b,这样b里面的方法修改,影响的地方会很多,但是如果在a里面包装b的的方法,影响的只有a。过度使用中间人和内幕交易 一个度的问题,描述的相反的情况。
  10. 过大的类(过于复杂的类)

    • 一个类里面有太多各自类型的属性,比如一个电脑,它只应该有8大件,不应该有具有主频,内存容量等信息,这些信息应该归属放到单独的组合类里面去,比如主频应该在 CPU上面,内存容量应该位于内存,电脑组合 cpu 和内存。
    • 面向对象设计原则类应该单一责任。
  11. 纯数据类(过于简单的类)

    • 如果一个类只有属性,没有方法,我们可以需要考虑是不是把应该属于这个类的行为放到了不合理的其他位置去了
    • 比如你有个电脑类,里面有8 大件,但是8 大件只提供了自己的属性,没有自己的对应的行为方法,所有的行为方法都在电脑这个类里面,8大类只是提供属性参数给电脑。这时候电脑这个类明显有问题,它变得极其臃肿,并且不便于拓展。
  12. 异曲同工的类(雷同的类)

    • 如果两个类有相同或者相识的功能,却有不同的定义,我们可以考虑是否真的需要两个这个的类,是否可以把他们合并起来?有些时候他们可能有意思,是些时候他们只会增加程序的复制度。
    • 比如你一个电脑插了两个鼠标(一般认为没意义),比如你的电脑接了2个显示器(一般认为有意义)
    • 比如你们系统只支持对公转账的大额支付,然后你订单以外设计了支付单(无意义),如果你们的系统需要微信,支付宝,银联支付等多种支付方式,然后订单以外设计了支付单(有意义)。
  13. 被拒绝的遗赠(基类属性行为冗余)

    • 继承实现这类父子关系的情况,如果父类继承下来的 属性或者方法,不是几乎所有子类通用的,那么后面这些子类的子类还要维护这些方法,这些属性还会被看到。
    • 这个不是太通用的属性或者方法可以考虑放到子类去,也可以考虑有别的接口和子类来管理这些接口或者属性
  14. 过多的注释的位置的代码

    • 注释是还好味道,但是当你需要写很长的注释来说明你在程序里面干了什么的时候,被注释额代码里面可能存在一些需要重构的怪味道。
    • 大量的注释的作用可能更应该用于描述为什么要这么干,以后打算怎么干,如果用于描述当前做了什么的注释太多,可能需要考虑代码结构是否应该优化

标签:24,重构,里面,数据,味道,方法,修改,比如,属性
From: https://www.cnblogs.com/cxygg/p/17304119.html

相关文章

  • 1124.表现良好的最长时段
    1124.表现良好的最长时段同类题目题目描述 给你一份工作时间表hours,上面记录着某一位员工每天的工作小时数。我们认为当员工一天中的工作小时数大于8小时的时候,那么这一天就是「劳累的一天」。所谓「表现良好的时间段」,意味在这段时间内,「劳累的天数」是严格大于「不劳累的天......
  • MIT 6.5840 2023 Spring(6.824)LAB1:MapReduce
    MIT6.58402023Spring(6.824)LAB1:MapReduce前言本次lab主要是完成一个基于RPC远程调用的单机单文件系统的简单MapReduce框架,并完成单词计数任务。基于golang实现,单Master,多Worker。实现worker的奔溃恢复(FaultTorrance),通过超时重新执行实现。主要的任务有,RPC调用参数及返回参数......
  • JavaWeb-24课-filter-2023-04-09
    Servlet类,没有乱码处理packagecom.feijian.servlet;importjavax.servlet.ServletException;importjavax.servlet.http.HttpServlet;importjavax.servlet.http.HttpServletRequest;importjavax.servlet.http.HttpServletResponse;importjava.io.IOException;public......
  • P2824 [HEOI2016/TJOI2016]排序 题解
    题目传送门前言线段树好题!!!!咕咕了挺久的一道题目,很早之前就想写了,今天终于找了个时间A掉了。题意给定一个\(1\)到\(n\)的排列,有\(m\)次操作,分两种类型。1.0lr表示将下标在\([l,r]\)区间中的数升序排序。2.1lr表示将下标在\([l,r]\)区间中的数降序排序。给......
  • 粒子行为计算软件2024 ncc 2024
    可以算质量、半径、球体积、球密度、球中心惯量之间的相互计算。Itcancalculatethemutualcalculationbetweenmass,radius,ballvolume,balldensity,andballcenterinertia. 单击此处下载download......
  • 2488. 统计中位数为 K 的子数组
    题目链接:2488.统计中位数为K的子数组方法:前缀和+哈希解题思路根据题意可知,在\(k\)是中位数的子数组中,比\(k\)大的数\(-\)比\(k\)小的数\(=\)\(0\)||\(1\)。那么将两种状态,小于\(k\)置\(-1\),大于\(k\)置\(+1\),计算数组的前缀和\(s\)。由于子数组要包含\(k\),所有左......
  • 从0开始自制解释器——重构代码
    在上一篇文章中,完成了对括号的支持,这样整个程序就可以解析普通的算术表达式了。但是在解析两个括号的过程中发现有大量的地方需要进行索引的回退操作,索引的操作应该保证能得到争取的token,这个步骤应该放在词法分析的阶段,如果在语法分析阶段还要考虑下层词法分析的过程,就显得有些复......
  • 1247. 交换字符使得字符串相同
    题目链接:[1247.交换字符使得字符串相同]方法:找规律解题思路由于只能两个字符串之间交换字符,单个字符串内不允许交换,因此如果只有一个字符对不相同,那么一定无法通过交换变为相同字符串,同理当不相同的字符对为奇数时,也无法通过交换变为相同字符。当不相同的字符对数为偶数时,现......
  • Mondriaan's Dream 【POJ2411】 题解
    Mondriaan'sDream【POJ2411】题解——ByZy注:原题中的\(h,w\)在本文中使用\(n,m\)代替。一.题意分析:题目要求给定一个一定大小的矩形棋盘,求出使用\(1\times2\)大小的木条填充一共有多少种方案。读题,发现数据范围\((1\leh,w\le11)\),考虑使用状压DP算法,于是......
  • HJ67_24点游戏算法_多维递归_DFS(深度优先搜索)
    思路:多维递归,深度有限遍历加减乘除四种情况。知识点:1、多维递归不能对传递的变量进行修改,否则无法回溯。应该传递一个新地址的变量,如代码所示,传递切片的列表,不修改列表  2、搜索遗漏。两括号比如((9-4)-1)*6选取任意一个数作为第一个运算数与24运算,不能找出所有24点的计算......