现在的位置: 首页 > 综合 > 正文

代码重构技巧

2013年10月06日 ⁄ 综合 ⁄ 共 2561字 ⁄ 字号 评论关闭

转载自:http://www.cnblogs.com/komojoemary/archive/2011/11/07/reconstruction.html

作为一个软件开发人员,你是否遇到过这样的情况:在阅读其他人的代码时,感觉很混乱,且大量重复;或是自己写的代码过一周或二周后再去看时,会发现其中很多的不足。如果是的话,那么恭喜你,最起码你是个有思想的程序员,你的境界比之前提升了。这个时候你是放之任之,还是决定亲自操刀来重构它呢?如果你选择后者,再次恭喜你,你不仅有思想,你还是个想到且能付诸实践的程序员。如果你选择前者,很遗憾,你可能已经深深的麻木了,你不再能感受到软件开发的乐趣所在,或许你曾经也有过激情,还请你再次拥有它,哪怕一点。


在编写一段新代码时,你不必考虑代码的重构,因为你根本无代码可以重构,你其实也不必太执着于代码编写前的结构设计,java与模式的作者也建议读者可以先编码,后修改设计,也就是我们常说的,先去做,然后再说。因为我们往往没有达到那么高的水平,在编码之前能够面面俱到,所以过分的花时间在代码设计上是不必要的。但是设计还是要做的,可以粗略点。当然注释不能在代码编写之后再去添加,那样将失去它的一半功能。一份好的注释一半是为了自己能够写出更加条理清晰的代码,另外一半当然是为了阅读人员的方便。

但当你整天面对的是一份已有的代码,已有的框架的时候,也就是你的那一亩三分地。这个时候重构是必然的。如果你已经麻木于ctrl+c;ctrl+v,你可能会完全的没机会体验到重构一份代码给你带来的乐趣。你可以试想一下,一份5000行的代码最后你用500行就替换了,那是怎样的一种成就感。
重构不一定会减少你的代码,不一定会提高系统的性能,但是重构一定会使得你的代码更加清晰,更加易于维护和扩充,更加健壮,也使得精简代码和提高性能变得更为可能和容易实现。 
那么一般你遇到什么样的代码的时候,应该考虑去重构它呢?怎么重构呢?
1.重复代码:这肯定是首当其冲的。如果你在一个以上的地方看到相同的数据结构,那么当可肯定:设法将他们合而为一。最常用的就是抽取成函数。
2.过长函数:程序越长越难理解。间接层所能带来的全部利益:解释能力,共享能力,选择能力--都是由小型函数支持的。如果你遇到了过长的函数,那么你应该更加积极进取的分解它。这个时候我们遵循这样一条原则:每当感觉需要以注释来说明点什么的时候,我们就把说明的东西写进独立的函数中,并以其用途命名。如果你给函数起了个好名字,读者就可以通过名字了解函数的作用,根本不必去看其中写了什么。
3.过大类:如果想利用单一的类做太多的事情,其内往往会出现太多的instance变量。一旦如此,重复代码就会接踵而至。这个时候,我们就应该不属于这个class的东西挪出去,放到它该有的位置,或是建个新的class,而不能只考虑使用方便,将过多不属于某个class的属性和函数放在其中,导致class臃肿不堪。
4.过长参数列表:我们常常会通过添加参数来达到扩展某个函数功能的作用,这在某个时候会出现过多参数的现象,然后方法的调用将变得晦涩且难以理解,参数的顺序还不能写错。这个时候我们可以将过多的参数列表做成一个有意义的实体对象,或者将函数替换成函数对象。
5.散弹式修改:如果每次遇到某种变化,你都必须在不同的class内部做出许多小修改以响应之,那么你恐怕就是碰到了散弹式修改的麻烦.如果需要修改的地方太多,你不但很难找到它们,也很容易忘记某个重要的修改,修改之后的测试工作也更加繁重。这个时候我们可以将这一系列相关的行为放进同一个class,如果还没有这样的class,你可以新建一个。
6.依恋情结:函数对某个class的兴趣高过自己所处的class。无数次的经验里,我们看到某个函数为了计算某值,从另一个对象那里调用半打的get函数。修改方法是:将这些函数移到它该去的地方。
7.数据泥团:数据项就像小孩子,喜欢成群结队待在一起。你常常可以在很多地方看到相同的三或四笔数据项:两个class内的相同属性,许多函数拥有相同的参数。这些总绑在一起出现的数据,应该放到属于它们自己的对象中。
8.基本型别偏执:java有8种基本类型,其它的都是对象。我们知道基本类型在内存中是保存在栈中的,对象则是保存在堆中的。显然,对象会带来更多的内存消耗。如果你有一组应该总是被放在一起的属性,那么你可以将它做成一个对象。
9.冗余类:你所创建的每一个class,都得有人去维护它,理解它。这些都是要花钱的。如果一个class不再承担它原本所规划的工作,那么它就应该消失,而不是让它继续得以残存在系统中。
10.夸夸其谈未来性:我们有时候会遇到这样的情况,一个函数拥有暂时没用到的参数,称为保留接口,或者是某张表拥有多个未使用到的字段,这些都是在假想中某天会使用到的数据,却存在于我们现在的系统中。或者是为了运用某种设计模式,抽象了过多的基类,过多的方法,这些东西中很多可能只有在测试用例里面才会出现可能性,这个时候,你可以考虑删除它。
11.钾昵关系:有时你会看到两个class过于亲密,如果发生在两个人上面,我们不必做卫道之士:但是对于class,我们希望它们严守清规。
12.过多的注释:别担心,我们并不是说你不该写注释。从嗅觉上讲,注释不是坏东西,但是常常有这样一种情况:你看到一段代码有着长长的注释,然后发现,这些注释之所以存在,完全是因为代码很糟糕。
13.令人迷惑的临时变量:有时你会看到这样的对象:其内某个instance变量仅为某种特定情势而设。这样的代码让人不易理解,因为你通常认为对象在所有时候都需要它所有的变量。在变量未被使用的情况下猜测当初其设置目的,会让人发疯。请为这个可怜的孤儿创造一个家,然后把所有与之相关的代码都拉进去,你会发现,这个孤儿其实也有父母。很常见的一个例子就是,某个class中有个复杂的算法,需要很多变量,由于实现者不想每次都传递常常的参数,所以将这些临时变量定义成了成员变量,而这些成员变量仅仅在这个算法中才有效,其它时候只会让人迷惑。这时候你可以将这个算法替换成一个class,做成一个算法对象,将这些变量做成这个class的属性,那么一切都将拨开云雾见晴天。

抱歉!评论已关闭.