文档章节

重构的原动力

开源中国驻成都办事处
 开源中国驻成都办事处
发布于 2013/12/30 23:39
字数 1777
阅读 29
收藏 0

Martin Flower那本经典书中说,重构是改善既有代码的质量。在实际的工作环境中,由于种种原因并不是想重构就能重构的。当然简单的一些重构,比如重命名,成员提升下降,合并重复代码,这些在力所能及的范围内,应该作为自己的职责,随时进行。那些想做而不能做到原因有:

人人自危

有些公司会对质量有严格的要求,对于错误的态度极不宽容。都担心自己犯错。不犯错的最好办法就是什么都不做。所有的改动不是朝着最优,最容易维护,最容易扩展到方向进行,二是朝着改动最少,最安全的方向进行。

忙于发布

由于计划安排的原因,我们总没有时间停下来,停下来思考,停下来审视什么才好才优雅。整个行业都忙于发布产品,加班是正常的,不加班才不正常。如果手上的任务都做不完,我们哪有时间来改善曾经任务的工作质量呢?关于软件的快节奏,有个非常讽刺的命题:我们经常做过头,却很多做对的事情。

谦逊与低调

谦虚是美德。但是过分的谦逊和低调,会让大家听不到你声音。我知道你可能该内心Fuck了做设计写代码的人N遍,但没有人知道你Fuck了她。最好的设计肯定是团队的结晶,是大家讨论妥协的结果。不用担心你的声音会带来什么样的眼神,你作为一个既有代码的涉及者,有权利发表自己的看法,有必要让团队知道你的感受。集体智慧才会有优美的代码。

如果你还有什么原因,也可以来吐槽一下?

本文讨论的重构是设计到整个产品架构的层面,是稍大层面的重构。它的目的是影响产品的进化。切不可那一些坏代码味道来套用本文。

真正开始重构还是有一些前置条件的。

1. 基准代码是100%正确的

重构的基本原则就是不改变既有代码的质量。因此基准代码可以假定为100%正确的。即使你发现了代码的一些问题,也不建议修复它们。如果有完善的变更控制流程,建议走变更控制的流程。将重构和修复分开,可以保证工作范围的界限清晰。

2. 重构是有商业价值的

公司企业都是利益驱动的。只有证明重构对其有商业价值时,才会得到它们的支持。作为一个码农你肯定知道重构是好的,但怎么告诉你的不懂技术的老板花钱雇你来做重构,并且你做的重构没有对客户产生任何附加的有用价值的时候?我们需要证明,按照现在的形势,维护或者新增功能的努力会越来越大,这就需要数据的说明。

3. 重构需要有能够保证不改变既有行为的验证机制

如何验证重构没有改变原来的行为?把所有以前的测试用例拿来跑一遍?这是不现实的。这样的测试成本太大,也不大可能做到,可能以前有些用例完全没有文档化。一种经验验证的方法,就是先写UT,保证UT覆盖既有代码的所有分支(如果没有覆盖,分析出是怎样的用户场景)和组合(可能很困难)。然后逐步做重构,每一步都要保证UT继续过。这个方法可以看作是重构型TDD。

4. 重构需要支持者

这里的支持者不仅仅是你的老板。还有同事的支持。老板的支持是保证流程层面能够顺利进行,同事的支持关系到重构的成败。

重构有一些误区。

1. 并不是直觉告诉你哪需要重构。需要数据作支撑。

这点跟优化有些类似。我们的直觉往往会欺骗我们。过早的优化可能害了我们,随意的重构可能拖住我们的后腿。

长期成功的软件开发肯定是需要Bug的管理工具。里面的数据记录了历史上我们犯过的所有错误,错误意味着不佳,那是我们需要改进的地方。一般我们将错误分类,比如分为显示、时序、交互等;也会将错误按照开发的功能分类。Bug管理工具会包含这些信息,当然还有很多其他可用的信息,比如是什么阶段引入的,修复花费了多长时间等等。

在我们拥有了这些数据的基础上,我们可以进行挖掘,找出哪些地方是需要改进的。注意是改进,而不是重构。因为可能有些因素不是我们能够控制的。比如流程的执行出了问题,第三方的库出来问题,框架的设计局限,等等,这些因素不是通过重构解决的。所以第一步需要找出哪些问题是可以通过重构逐步解决的。

找出了需要重构的问题后,我们需要一个优先级列表,列表中的每一项是一个类型的问题,也就是得到一个问题领域。不是所有的问题领域都值得解决。比如如果一个功能非常稳定,不需要以后再做功能扩充,那就没有必要去进行重构。比如有些领域刚开始问题非常多,但逐渐成一个下降趋势,这表示改功能逐渐趋于稳定,也就没有必要去进行重构。通过分筛选,再结合我们拥有的资源和优势,就能定位出需要做重构的问题领域了。

得到问题领域的列表,我们就可以真正开始重构了。

2. 重构是一个渐进的过程,需要有大方向。

重构肯定不是一步到位的。举个例子,如果一个平台决定采用C语言,通过优化结构的方式做重构,另一个平台,决定采用C++,才用OO,提炼一些模式来做重构。这肯定是两个完全不同的方向。只有选定方向了,才能有自己的路线图。

从稍小的角度来看,也只有有了一个团队级的重构路线图,大家才会逐渐向重构的方向靠拢。如果没有这样的路线,四下散开,增加的就只有复杂度了。

注,某次研讨会补上的笔记

© 著作权归作者所有

共有 人打赏支持
开源中国驻成都办事处
粉丝 84
博文 287
码字总数 335913
作品 0
成都
程序员
如何深度重构UIViewController实例-直播界面

如何深度重构UIViewController实例-直播界面 之前写过一篇深度重构UIViewController,中间简单的提到过我现阶段是如何重构Controller这一层的。之后不少同学联系我索要demo代码,果然是no co...

法斗斗
2016/12/28
5
0
浪潮“计算+”:聚焦三大计算,打造数据社会原动力

10月26、27日,两年一度的Inspur World大会如期而至。本次大会的主题是“Only Data 数据进化世界”。2000多名重量级政府、企业客户及合作伙伴济济一堂,围绕数据社会化的发展趋势,就云计算、...

玄学酱
05/10
0
0
Java重构示例

1.尽量简洁 1.1重构前 if ( flag == 1 ){ }else{ } 1.2重构后 return flag == 1; 2.使用三位运算符 2.1重构前 if ( "Male".equals(gender) ) { }else{ } 2.2重构后 return "Male".equals(gen......

动听的椰子
2016/04/08
107
0
什么是重构,什么不是重构

有时候,会有程序员跑到我这里说他们不喜欢某个东西的设计,“我们需要给它来个全面的重构”,来纠正里面的错误。哦,哦。这听起来可不是个好主意。而且这听起来也不是重构… 重构(Refactor...

景德真人
2012/05/14
2.7K
14
重构之十六字心法

本文作者:伯乐在线 -ThoughtWorks 。未经作者许可,禁止转载! 欢迎加入伯乐在线专栏作者。 这篇文章是我写过的所有文章里最难产的一篇,前前后后斟酌酝酿了好几个月。因为重构对于我来讲真...

伯乐在线
2017/05/10
0
0

没有更多内容

加载失败,请刷新页面

加载更多

TypeScript基础入门之高级类型的多态的 this类型

转发 TypeScript基础入门之高级类型的多态的 this类型 高级类型 多态的this类型 多态的this类型表示的是某个包含类或接口的子类型。 这被称做F-bounded多态性。 它能很容易的表现连贯接口间的...

durban
25分钟前
0
0
tomcat中的几种log catalina localhost

体会 catalina.out catalina.log 是tomcat的标准输出(stdout)和标准出错(stderr) cataliana.{yyyy-MM-dd}.log和localhost.{yyyy-MM-dd}.log 是通过logging.properties配置的tomcat自己运行的......

onedotdot
46分钟前
1
0
Oracle return exit continue

常在循环体中看到下面3种语句: return exit continue 举例说明 啥都没有 -- none begin for i in 1 .. 10 loop if i < 5 then dbms_output.put_line('i < 5, i = ' || to_char......

taadis
今天
3
0
JSONObject 转换时出错 InvocationTargetException

JSONObject 转换时出错java.lang.reflect.InvocationTargetException 一时看不出来是什么问题。 挺奇怪的。 百度参考了一下这个 网页的解决方案 说是类型不对,空? 仔细查看代码,果然是有一...

之渊
今天
3
0
no such module 'pop'问题

在github上 clone 了一个 swift 项目,编译时提示"no such module 'POP'"错误,查了一下居然是因为podfile中指定的最低版本是iOS 11.0,大于我测试手机的iOS版本10.3.3,将Podfile中的最低版...

yoyoso
今天
3
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部