码迷,mamicode.com
首页 > 其他好文 > 详细

说说什么是重构(二)重构的过程

时间:2015-05-29 15:48:04      阅读:99      评论:0      收藏:0      [点我收藏+]

标签:重构




上一篇文章主要是说了说什么是重构,重构都在什么情况下开始。而这篇文章,则主要是讲讲重构的过程中,需要注意哪些东东。还有就是如何进行重构。


背景


说到底,重构无非就是为了让代码更加优雅,更加简练,更加高效。重构的结果就是找到一个平衡点,使得项目不仅能够稳定的运行,还能够很容易的被程序员理解,以至维护起来不用那么辛苦。那么,下面就说说重构过程中应该注意哪些事项,以及如何进行重构。


建立测试体系


如果你想进行重构,首要前提就是要有一个稳定、可靠的测试环境。作为开发人员,大部分的时间不是消耗在编写代码,而是用来做调试,也就是我们说的测试。一般情况下,修复错误是比较快的,问题就在于,如何能快速的定位错误位置,或者说是如何能快速的找出错误,有时你甚至会花费一整天的时间来排查错误,而且可能还无果而终。

鉴于这样的问题,你就不得不建立自己的一套测试体系,这个测试体系会帮你更快的发现问题,而不至于等到发布测试环境之后,让测试人员再给你提 bug 。当然,有些 bug 是我们测试不出来的,那么为什么不把我们能解决的提前解决掉呢,这样不是更好吗?

至于如何建立测试体系,这个一般是比较规范的公司都会有的。这里我推荐几个单元测试工具,可以基于单元测试工具进行搭建。我自己用的是 jUnit 测试框架,同时你也可以使用 TestNG ,TestNG 也是一款比较出色的测试框架。由于现在的大部分工程都是基于 maven 开发的,也有使用更加先进的 gradle 的,当然也不排除使用 ant 的,这些自动化的构建、部署工具,能够很好的集成测试框架,对于测试来说,大大的方便了开发人员。


重新组织函数


我记得《重构》一书中,作者说过,他的重构手法中,大部分是对函数的整理工作,使之更恰当的包装代码。在我看来,其实就是单一职责和消除重复的体现。每个函数只干一件事,函数不要有太多的职责,否则,函数的体积会非常的庞大,不仅对于维护人员来说增加了困难,而且必然会增加重复性、冗余的代码,使得函数越来越臃肿,最终导致崩溃。因此,务必要保持函数的简洁性,始终做一件事即可。

那么,消除重复则是指的,在函数的调用过程中,尽量不直接 copy 所调用函数的实现,而是把多处用到的代码块单独提取出来,抽象成一个新的方法,或者一个新的类,而在用到的地方,直接调用新方法或新类,这样就能有效的避免重复代码导致的恶果。


重新组织对象特性


在对象的设计过程中,决定把责任放在哪儿,也是很重要的事。这是因为,类往往会因为承担过多的责任而变得臃肿不堪,导致在调用关系上如同乱麻,没有一个清晰的结构。那么,该如何组织对象的特性呢?

其实,在我们起初设计类的时候,就因为考虑的过少或过多, 导致类的职责并不单一。为了解决职责过多的问题,首先在设计类的时候,就要以单一职责为设计思想,把不相干的函数尽量放到新类中,比如,我要判断一个对象是否为空,那么首先要考虑这个判断为空的方法是不是在别的对象也会用到,如果会的话,那么就要考虑把他迁移到一个新类中,这个新类就是只进行对想验证的工具类。

重新组织对象的特性,其主要的工作还是在于分析类的结构,以及类的职责,弄清楚这个类是做什么的,哪些工作不适合他做,哪些工作是必须要做的,那么重构起来会非常方便的。


简化条件表达式


有时候,由于业务逻辑的复杂性,很可能会使用到复杂的条件表达式,甚至要判断的条件会有很多很多,这不仅仅会影响程序的可读性,同时也给维护增加成本,更加不利于扩展等。因此,这种情况下,就要对条件表达式进行简化,那么该如何简化呢?

说到简化条件表达式,说到底还是对业务的耦合,能不能把对业务的耦合抽取出来,是根据这样的业务在项目中存在的多与否,以及有没有相似性,能不能够进行复用。面向对象的封装不就是为了对象的复用嘛。如果某个函数中,if 片段包含太多的话,而这个函数在其他类里没有涉及到,那么,你就可以将 if 段提炼出来,构成一个独立的函数。如果在其他类里有涉及的话,就要优先考虑能否采用某个设计模式,或者利用多态来实现了。


简化函数调用


在面向对象技术中,最重要的概念莫过于“接口”了,也有很多开发者经常称是“面向接口编程”。其实,定义一个良好的接口,是开发面向对象软件的关键。那么首要的问题就是,在函数的命名上,要遵守规范的命名方式,我比较喜欢的还是首字母小写的“驼峰式”命名。单词的选择,我个人认为,最好还是选择与所要操作行为意思相同的英文单词进行命名,这样能够很好的理解,毕竟不懂的单词可以查字典嘛。

然后,就是关于接口定义的参数问题了。记得上一篇文章中也说过,参数不能太多,太多的话,不仅影响可读性,在后续的维护中也可能会根本搞不清这些参数都是做什么的。尤其是并发编程的时候,不仅参数名很长,参数的个数也是很多的,而且还要考虑不可修改的问题。其实,完全可以采用不可修改的对象来实现,把参数包装到对象中,给函数传递对象来实现数据的传递。不过,这一块的重构还是需要谨慎一些的。


处理概括关系


还有一种关系,在重构中需要特别注意,就是“继承”。在面向对象的设计中,继承给我们提供了很大的便捷性,子类继承父类,子类便可以拥有父类的所有属性和方法(私有的除外)。然而,在重构之时,多个子类中的共同属性,就可以考虑放到父类中,这样即可避免了重复的出现。当然,需要考虑的还有构造函数等。反之,如果父类中的属性或函数在其他子类中是没有用到的,或者说是无用的,而只是针对某一个子类才有的,那么就可以考虑把该属性、函数下移至子类。


结束语


说了这么多,也列举了不少方法,但是回过头来想想,重构的最本质的东西还是对事物的抽象、封装和复用。其实,对代码的提炼,就是思想的提炼,就是对面向对象思想的进一步理解。

《重构》带给我的不仅仅是一个修改代码的过程,他还让我体会到代码原来还可以这么优雅,这也就应了那句话,代码也是有生命的,就看你能给她赋予多长的时间。



说说什么是重构(二)重构的过程

标签:重构

原文地址:http://blog.csdn.net/happylee6688/article/details/46236431

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!