代码重构的场景总结

论坛 期权论坛 期权     
秦子帅   2019-7-21 04:46   3134   0
点击上方蓝字关注

来源:奔跑吧李博https://www.jianshu.com/p/7e8bd46d37ba
[h2]详解核心思想:拆细、公用[/h2]重构可以是修改变量名、重新安排目录这样简单的物理重构,也可以是抽取子函数、精简冗余设计这样稍许复杂的逻辑重构。但均不改变现有代码的功能。
了解敌人——丑陋的代码
  • 臃肿的类开发者缺乏对最基本的编码原则,即“单一职责原则”(SRP)的理解。开发者不去思考这些功能是不是应该放在这同一个类中,导致这些类会变得很臃肿,造成一个类几千行,让下一个接盘侠欲哭无泪。
  • 臃肿的方法好几十上百行的一个函数堆在一块,用面向过程的思想来写代码。
  • 函数参数过多函数参数过多会导致调用者对方法难以理解,参数弄混。想象一下一个函数连续传5个int值参数,能分清谁是谁吗?建议可以将参数组成一个对象传入。
  • 层层嵌套的判断如果逻辑不复杂尽量减少if-else的分支包裹,他人太难阅读。比如不满足条件了直接return,不走其他代码,这样可以减少一层嵌套。
  • 满篇跑的常量值一个类里面出现各种未命名的常量值。0,1,200等等铺天盖地。这种状态码意义改了,改代码会把你改哭的。难道就不能先声明一个统一的常量变量来使用吗。
  • 模棱两可的命名不能根据名字一眼看懂它的功能的命名不是一个好命名。当然生僻的单词除外。模糊的,没有功能意义的命名会给阅读造成很大困难。
[h2]重构之道[/h2]
  • 分拆大函数: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转化在其中,屏幕尺寸相关方法在其中,日期转化在其中,加密的索性也放在其中,那有无网络,网络类型判断也加入吧。这不就像垃圾场了吗,各类杂物都堆在其中,不符合单一职责原则,应该按照如上的功能块分解成多个职责单一的类。类多不要紧,关键要做到职责单一。
  • 将满篇跑的魔鬼数字和字符串用定义的常量表示。如果只是某个类或者某个模块需要用到该常量,就声明到对应类中。如果是全局项目都会用到的常量,就提升到项目的常量配置文件中。
[h2]面试题[/h2]
几百道不错的真实大厂Android面试题FDF




获取方式:文末加我的微信,备注面试题,我发给你我的微信:



—————END—————


分享到 :
0 人收藏
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

积分:
帖子:
精华:
期权论坛 期权论坛
发布
内容

下载期权论坛手机APP