狗屎一样的代码如何重构?
(一)重构原则
1、何谓重构
对软件内部结构的一种调整,目的是在不改变软件可观察行为的前提下,提高其可理解性,降低其修改成本。
另一种解释是:使用一系列重构手法,在不改变软件可观察行为的前提下,调整其结构。
2、为何重构
改进软件设计:如果没有重构,程序的设计会逐渐变质,重构很像是在整理代码,你所做的就是让所有的东西回到应处的位置上。
帮助找到bug:对代码进行重构,可以深入理解代码的作为,在搞清楚程序结构的同时,想不把bug揪出来都难。
提高编程速度:良好的设计是快速开发的根本,改善设计、提高可读性,减少错误,这些都是提高质量。
3、何时重构
任何情况下我都反对专门拨出时间进行重构。重构本来就不是一件应该特别拨出时间做的事情,重构应该随时随地的进行。
三次法则
大多数重构都为程序引入了更多的间接层,重构往往把大型的对象拆成多个小型的对象,把大型的函数拆成多个小型的函数。但是,间接层是一把双刃剑。每次把一个东西分成两份,你就需要多管理一个东西。如果某个对象委托另一个对象,后者又委托另一个对象,程序会愈加难以阅读。【文末有干货分享,满满的免费资料!】
重新组织函数
1、提炼函数
动机:看到一个过长的函数或者一段需要注释才能让人理解用途的代码,将这段代码放一个独立的函数中;
做法:
2、内联函数
一个函数的本体与名称同样清楚易懂。在函数调用点插入函数本体,然后移除该函数。
动机:一群组织不甚合理的函数。你可以将它们都内联到一个大函数中,再从中提炼出组织合理的小型函数。
使用的太多的间接层,使得系统中的所有函数都似乎只是对另一个函数的简单委托,造成在委托动作之间晕头转向。
做法:
有一个临时变量,只被一个简单的表达是赋值一次,而它妨碍了其他重构手法。将所有对该变量的引用动作,替换为对它赋值的那个表达式自身
double basePrice = anOrder.basePrice();
return (base > 10000 );
替换为:
return (anOrder.basePrice > 1000);
4、以查询取代临时变量
你的程序以一个临时变量保存某一表达式的运算结果。将这个表达式提炼到一个独立的函数中。将这个临时变量的所有引用点替换为对新函数的调用。此后,新函数就可被其他函数使用。
替换为:
临时变量只在所属的函数中可见,如果把临时变量替换为一个查询,那么同一个类中的所有函数都将可以获得这个份信息,这将带给你极大的帮助,使你能够为这个类编写更清晰的代码。
5、引入注释性变量
你有一个复杂的表达式。将该复杂表达式(或其中一部分)的结果放进一个临时变量,以此变量名称来解释表达式用途。
替换为:
表达式有可能非常复杂难以理解。这种情况下,临时变量可以帮助你将表达式分解为比较容易管理的形式。
在条件逻辑中,你可以用这项重构将每个条件子句提炼出来,以一个良好命名的临时变量来解释对应条件子句的意义。另一种情况是:在较长的算法中,可以运用临时变量来解释每一步运算的意义。
6、分解临时变量
你的程序有某个临时变量被赋值超过一次,它既不是循环变量,也不被用于收集计算结果。 针对每次赋值,创造一个独立、对应的临时变量。
替换为:
如果临时变量被赋值超过一次,就意味着它们在函数中承担了一个以上的责任。如果临时变量承担多个责任,它就应该被替换为多个临时变量。每个变量只承担一个责任,同一个临时变量承担两件不同的事情会令代码阅读者糊涂
7、移除对参数的赋值
代码对一个参数进行复制。以一个临时变量取代该参数的位置。
替换为:
如果代码的语义是按引用传递的,请在调用段检查调用后是否还使用了这个参数。
8、替换算法
想要把某个算法替换为另一个更清晰的算法。将函数本体替换成为另一个算法。
替换为:
(未完)
分享免费学习资料
针对于还会准备免费的Java架构学习资料(里面有高可用、高并发、高性能及分布式、Jvm性能调优、MyBatis,Netty,Redis,Kafka,Mysql,Zookeeper,Tomcat,Docker,Dubbo,Nginx等多个知识点的架构资料)
为什么某些人会一直比你优秀,是因为他本身就很优秀还一直在持续努力变得更优秀,而你是不是还在满足于现状内心在窃喜!希望读到这的您能点个小赞和关注下我,以后还会更新技术干货,谢谢您的支持!
有需要获取免费资料可点喜欢关注我,加秋秋群:856443934获取!
(部分资料如下)