专栏首页Linyb极客之路代码重构的场景总结

代码重构的场景总结

核心思想:拆细、公用

重构可以是修改变量名、重新安排目录这样简单的物理重构,也可以是抽取子函数、精简冗余设计这样稍许复杂的逻辑重构。但均不改变现有代码的功能。

了解敌人——丑陋的代码

臃肿的类

开发者缺乏对最基本的编码原则,即“单一职责原则”(SRP)的理解。开发者不去思考这些功能是不是应该放在这同一个类中,导致这些类会变得很臃肿,造成一个类几千行,让下一个接盘侠欲哭无泪。

臃肿的方法

好几十上百行的一个函数堆在一块,用面向过程的思想来写代码。

函数参数过多

函数参数过多会导致调用者对方法难以理解,参数弄混。想象一下一个函数连续传5个int值参数,能分清谁是谁吗?建议可以将参数组成一个对象传入。

层层嵌套的判断

如果逻辑不复杂尽量减少if-else的分支包裹,他人太难阅读。比如不满足条件了直接return,不走其他代码,这样可以减少一层嵌套。

满篇跑的常量值

一个类里面出现各种未命名的常量值。0,1,200等等铺天盖地。这种状态码意义改了,改代码会把你改哭的。难道就不能先声明一个统一的常量变量来使用吗。

模棱两可的命名

不能根据名字一眼看懂它的功能的命名不是一个好命名。当然生僻的单词除外。模糊的,没有功能意义的命名会给阅读造成很大困难。

重构之道

分拆大函数:Break Method

当函数比较大了,就可以根据功能节点分拆成多个小函数,也许其中的小函数还可以公用。比如结算购物车,包括计算各类商品的总价,再计算折扣,再计算满减优惠,如果一个方法执行完,那么别人要只要逻辑就要从头到尾读一遍。而分别拆分成三个,一眼就能看出这段逻辑先后做了什么。写方法切忌一口吃一个胖子。

封装到父类:

如果多各类要执行相似的功能和代码,可以把该方法放到它们的父类中,或者提取出来成业务工具类。

Move Method----方法迁移

遵守“单一职责”原则,当类中的方法不适合放在当前类中时,就应该为该方法寻找合适下家。移到与方法耦合大的类中。当一个方法被其他类使用比在它所在类中的使用还要频繁时,我们就需要使用迁移方法重构了——将方法迁移到更频繁地使用它的类中。

Move Field----搬移字段

当在一个类中的某一个字段,被另一个类的对象频繁使用时,我们就应该考虑将这个字段的位置进行更改了

Extract Class----提炼类

一个类如果过于复杂,做了好多的事情,违背了“单一职责”的原则,所以需要将其可以独立的模块进行拆分,当然有可能由一个类拆分出多个类。

对类的细化也是为了减少代码的重复性,以及提高代码的复用性,便于代码的维护。

提升方法、字段(Pull Up Method)

将方法向继承链上层迁移的过程。用于一个方法被多个实现者使用时。在继承的体系中,当多个类使用了相同或类似的方法,就可以考虑将该方法抽取到基类,没有基类就创建一个。字段提升同方法。

降低方法

即父类抽象方法让多个子类实现。多个子类有相同的功能但是有各个具体的实现方法,那么这种封装就可以用多态性了,父类创建一个抽象方法,将方法实现降低到子类。

重复代码的提炼

有时候为了赶项目进度,尽快完成功能,会偷懒将实现功能的一片代码复制一遍,直接套用。这种把多余的删掉,保留一个,也许只需传一两个参数就可以封成一个方法供多处调用。

重命名变量(类、方法、变量)

这个很重要,可以不夸张地说,命名的水平就体现了编程能力的高低。在重构的过程中,当发现类名,方法名在当前版本不符合它的功能含义,就该考虑对其重新命名。

补加注释

对于全局变量,公用函数,逻辑复杂的地方添加注释,弥补之前的遗漏。

将较长的判断或代码运算用临时变脸暂存

if(stateCode = OK && datas != null && canShow)
function(Math.random((num1-num2)*num3))

如上这种长长的判断条件和参数会使 这种代码应该先将if判断条件写成一个变量,放入变量判断,将function参数写一个局部变量保存结果,再传入方法。

使用泛型封装成统一的方法或类

函数要避免过多的参数造成阅读的复杂性

public void requestPhoneThirdRegister(String loginway, String nickname, String openId, String token, String expires, String phone, final CallBackimpl callBackimpl)

用这样的方法直接传参数就太长了,严重降低代码可读性。我们可以将参数变量写到一个实体类中,通过构造方法初始化对象属性值,只需要传递一个对象就搞定,也解决了增减参数带来的变动问题。

嵌套条件分支优化

if(){
 if(){
 if(){
 }
 }
 }else{
 }

相信大家也见识过不少这样的箭头代码,像怎么也解不开的死结。遇到这种代码,一定要尽可能要优化。通常做法:判断语句,if条件成立,执行代码块,诶,这样就生成了一个嵌套层级。

优化的核心思想:直接判断不满足的条件,if条件成立,直接return,尽快跳出方法来减少嵌套的层级。

第二种:将条件判读合并

尽量避免双重否定的条件

private boolean isChecked(){
 if(){
 return true;
 }
 }

一个条件方法。

if(!isChecked()){
}

然后用否定来判断这个条件,这样可能会一时之间转变不过来导致条件判断反了。当然头脑灵活的忽略这条。

去除东北乱炖的Util类

当我们在写代码中偶然间需要抽出公用方法时,一时之间找不到合适的类去放置,然后就随意地放进了XXUtil或XXManager类中。长此以往,该类所含功能越来越杂,dp和px转化在其中,屏幕尺寸相关方法在其中,日期转化在其中,加密的索性也放在其中,那有无网络,网络类型判断也加入吧。这不就像垃圾场了吗,各类杂物都堆在其中,不符合单一职责原则,应该按照如上的功能块分解成多个职责单一的类。类多不要紧,关键要做到职责单一。

将满篇跑的魔鬼数字和字符串用定义的常量表示。

如果只是某个类或者某个模块需要用到该常量,就声明到对应类中。如果是全局项目都会用到的常量,就提升到项目的常量配置文件中。

本文分享自微信公众号 - Linyb极客之路(gh_c420b2cf6b47),作者:出云小课堂

原文出处及转载信息见文内详细说明,如有侵权,请联系 yunjia_community@tencent.com 删除。

原始发表时间:2020-06-03

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • java代码优化的若干细节

    代码优化,一个很重要的课题。可能有些人觉得没用,一些细小的地方有什么好修改的,改与不改对于代码的运行效率有什么影响呢?这个问题我是这么考虑的,就像大海里面的鲸鱼...

    lyb-geek
  • 有哪些新手程序员不知道的小技巧?

    2. 不要写代码前过度计划,在一头钻进代码前做点计划是好事,但是即便是好事,也可能物极必反。喝太多的水都会使你中毒呢;

    lyb-geek
  • 干货 | 写好Java代码的30个技巧

    成为一个优秀的Java程序员,有着良好的代码编写习惯是必不可少的。下面就让我们来看看代码编写的30条建议吧。

    lyb-geek
  • (持续整理中)Visual Studio 中 C# 代码分析规则集中每一项的含义 (stylecop ruleset)

    发布于 2018-02-07 13:55 更新于 2018-03...

    walterlv
  • 聊一聊SLAP:单一抽象层级原则

    作为程序员,我们总是和方法打交道,不知不觉都会接触Long method(方法体较长的方法),不论是自己写的还是他人写的,而Long method(长方法)往往...

    技术小黑屋
  • python forkping

    def ping(host):   result = subprocess.call('ping -c2 %s &> /dev/null'%host,shell...

    py3study
  • Prometheus入门实践 顶

    Prometheus下载地址 Prometheus相关文档 Prometheus官方文档

    BGBiao
  • 超实用!这 6 个小程序,你生活中一定用得上

    「倒数记日」这款小程序能帮你记录生命中那些重要的日子,让你不再错过每一个难忘的时间。

    知晓君
  • QtCreator查看汇编代码

    Qt君
  • 你一直弄不懂的Java反射机制

    Java反射机制, 啧啧, 当你看到这几个字的时候就有一种不好的预感, 没错, 这个东西是不怎么好理解, 所以特开此篇, 从实用的角度, 用确切的代码来讲解一下...

    Java团长

扫码关注云+社区

领取腾讯云代金券