文档章节

重构的原动力

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

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

人人自危

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

忙于发布

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

谦逊与低调

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

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

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

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

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

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

2. 重构是有商业价值的

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

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

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

4. 重构需要支持者

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

重构有一些误区。

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

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

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

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

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

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

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

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

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

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

© 著作权归作者所有

共有 人打赏支持
上一篇: TDD问答录
开源中国驻成都办事处
粉丝 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
软件体系结构的重构——定义

以前做过一个产品,共分为三层:平台层,应用服务器层,应用层。其中有一个业务流程,实现是在应用层,但它那里的信息不全,需要通过应用服务器层向平台层获取必要的业务数据,然后通过应用服...

晨曦之光
2012/06/06
63
0

没有更多内容

加载失败,请刷新页面

加载更多

Android 通过DrawableInflater加载自定义Drawable

一、Drawable 在Android系统张,图形图像的绘制需要在画布上进行操作和处理,但是绘制需要了解很多细节以及可能要进行一些复杂的处理,因此系统提供了一个被称之为Drawable的类来进行绘制处理...

IamOkay
14分钟前
1
0
灵活无处安放,所以选择流浪....《漆黑的空间》& 《灰色轨迹》

灵活无处安放,所以选择流浪....《漆黑的空间》& 《灰色轨迹》

yizhichao
20分钟前
1
0
Kafka+Flink 实现准实时异常检测系统

1.背景介绍 异常检测可以定义为“基于行动者(人或机器)的行为是否正常作出决策”,这项技术可以应用于非常多的行业中,比如金融场景中做交易检测、贷款检测;工业场景中做生产线预警;安防...

架构师springboot
今天
7
0
DecimalFormat 类基本使用

/* * DecimalFormat 类主要靠 # 和 0 两种占位符号来指定数字长度 * 0 表示如果位数不足则以 0 填充 * # 表示只要有可能就把数字拉上这个位置 * */ public static void main(String[] args){...

嘴角轻扬30
今天
4
0
This APT has Super Cow Powers.

在Debian/Ubuntu上,apt包管理器内嵌着一个彩蛋. 如果你在命令行界面输入 apt help 在最后一行能找到This APT has Super Cow Powers. 说明该apt具有超级牛力 牛力是个什么梗? 则说明你的系统...

taadis
今天
3
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部