2011年1月26日
13:52
2510年。考古队挖出一块硬盘,记录这2010年R公司的代码。他们从redgate公司的档案柜内找到 reflector反向出来了这些源代码,发现古人已经在编码方面注意标准化并且使用工具自动化这个过程。大家惊呼,哇咦,古人已经很聪明了。
我们的重构流程推行了两年。经过一段时间对重构流程的梳理、慢慢的建立和抛弃一系列的思想,然后不断的简化、淬炼、抽象,逐步的形成到具体的实践方法。本文就是我的简要的思考过程。我希望以此帮助大家了解我们在高质量编码方面的价值观,从而更好的实践新的流程。
重构是有效果的。我从这个过程中得到几点看法:
<!--[if !supportLists]-->1. <!--[endif]-->对产品。经过有意识的、有节奏的代码重构,代码往往变得更加漂亮;产品也变得比较容易维护。维护代码的痛苦有所减轻。
<!--[if !supportLists]-->2. <!--[endif]-->对个人。部分人养成了重构的习惯,知道一些常用的重构手法,知道如何利用工具来做安全的、快速的重构。code reviewer 本身的进步是最大的。
问题也不少。
<!--[if !supportLists]-->1. <!--[endif]-->养成重构的习惯的人不多。很多个人的成长看得出来是非常缓慢的,亦步亦趋的。技巧层面的CheckError得到了广泛的应用,而重构技术方面(系统而全面的)并没有得到重视。有时候我也需要问问自己:写出好代码的能力难道真的只有少部分人才能够具备吗?
<!--[if !supportLists]-->2. <!--[endif]-->代码一旦写成,即使采用系统的重构方法,代价也还是会很大。
<!--[if !supportLists]-->3. <!--[endif]-->低质量编码的习惯养成了,就更加难以清除。
<!--[if !supportLists]-->4. <!--[endif]-->Code reviewer现在是非常缺乏的。
当前的重构流程好像有些依赖性。这两年的做法一直是:大家写代码,我来做审查,指出方法,然后讨论修改。这样的做法就像是上游进行污染、下游加了一个污水处理厂一样——并且编码者总是不能建立上游治污的意识——甚至支持大家的新看法:“治污是污水处理厂的事情”。于是当代码大量的复制,功能大量的增加、组内成员变多后,以“一个人的力量”来发现问题,提出重构的方案,然后修改的这样的模式是很难走下去的。培训做了很多次,听就听了,真正动手的是比较少的。个案的解决一个个的重构问题,然后希望大家的代码意识得以提升是非常困难的,最后依然是时间问题,大家在排出日程来做这个工作方面总是觉得困难。学习和实践重构是程序员的责任。而现在这一点是如此的困难,以至于我们好像是一个进退维谷的境地!
继续,闯出新天地。清理下这些年乱麻般的思路,把它变成可以实践的套路,就是一条:Code Diff。
做法的关键就是Code Diff Daily(每日代码差别比较)。要点是定期、流程化、轮值。
<!--[if !supportLists]-->1. <!--[endif]-->定期。每天下班前15分钟就来做。项目组自己有代码高质量的意识,信仰高质量代码的对产品和团队的价值,建立开放坦诚的沟通环境,并且通过Code diff把理念落实到每一天。
<!--[if !supportLists]-->2. <!--[endif]-->流程化。大家围在一起,通常是面对投影仪,有时候也是看一台电脑。然后,打开Svn Log,把今天提交的代码修改一一比较,查看代码问题,提出改进意见。开放环境的创建首先需要管理服务(Management as Service )。
<!--[if !supportLists]-->3. <!--[endif]-->轮值。Code Review发起人是轮值的。管理者应该为程序员提供更加友善、健康、正面的沟通环境。整个环境不但可以解决代码问题,还能够增进沟通,帮助大家说出想说的,让大家接受可能是难以接受并且习以为常。一句话,把问题摆在桌面上。
<!--[if !supportLists]-->4. <!--[endif]-->尽可能采用自动化
流程就是这样,通过流程让大家更加开放的进行高质量编码。这是一个基础,一个管理服务。但是仅仅有了流程还是不够的。大家唯有理解了我们的价值观,才能让大家得到更多的益处;否则必然是简单的亦步亦趋、有样学样。这是我不想看到的。
克服一个拖后腿的“轻浮”想法。有人认为:“指出代码的问题是很容易的事情,人人都可以做到看到别人代码的问题”。这样的观点在我看来是非常轻浮的。重构仅仅在《重构》一书内就有上百的方法,大的原则是消除重复和容易,职责分离等等,小的步骤就非常的多了,遇到一个具体问题,运用这么多的方法,首要是投入和学习、实践,其次是灵活组合多种方法,小步的、安全的达到重构的效果。这些年来,国外的敏捷咨询机构进入中国的越来越多,比如Thoughtworks,Odd-e,也有越来越多的公司采用了敏捷,比如ActiveNetwork,华为。而敏捷的一个核心实践就是重构,是咨询公司的主要收入源。而从我接触的一家咨询公司的评价上看,他们的很多客户做的并不好。可见,把重构视为比较简单的事情是过于轻浮的看法。感觉到是一回事,瓜分豆析的执行是另一回事。以前就常常有人说,“你看这个代码真的太…”,然而让他找出方法,他总是说,“这简直不可能,要考虑稳定,考虑进度...”。切。千人诺诺,不如一士谔谔。拿出妥善的、成套路的方法,并且一以贯之,才是这个王道。
观察高效程序员的做法,逐步厌弃低质量代码。我发现越是编码质量高的程序员,越是自然的排斥不良的编码。和他们的交流代码,常常发现他们会很愤恨的嘟嘟囔囔:“你看嘛,干嘛啰嗦,换个方法多简洁;这里的写法根本没有必要;还有这里,命名和大小写都成问题”。因为厌弃,才会逼着自己写出优秀的代码来,逐步养成新的习惯,“下笔如有神”,自然的写出漂亮的编码来。而整个团队的所有人都应该向这个信仰高质量代码的程序员一样,信仰高质量代码的对产品和团队的价值,相信自己在今天的投入会在未来得到回报。回报可能包括产品的稳定性、可维护性,个人水平的提升,产品的竞争力提升,balabala。
程序员的心理过程需要关注。很多程序员在遇到其他人编写的编码时,也会有“做好我自己就行“的鸵鸟思想。看到不好的代码,常常不好意思直接的指出来——怕伤了面子,也怕被拒绝。理解我们的价值观,就是为了释放程序员的能力,让大家可以自由的、不怕争论的提出自己的做法、精炼自己的实践。
从源头狙击。以往的做法都是编码后检查,然后提出修改。存在更好的工具来帮助code reviewer从程序员一开始编码就强制规范。如TFS可以在提交代码前自动检查Naming规范,复杂度。再比如TeamCity可以查找重复代码。Reviewer 可以不必花费太多时间查验基本代码规范,做更有价值的架构分析和重构。程序员可以清晰的看到规范的存在,如同编译错误一样很容易定位这一类问题。
代码像水一样,但是你无法保证你就是下游或者上游——他们是相关的,任何人不能保证今天某人写的代码,不会明天流到你这里来,而你也不能保证你的代码某天不会流到某人那里。所以,建立一个开放坦诚的环境是必须的。建立一个高质量的价值观,并通过Code Diff 分解到每一天是必要的。
详细的做法,请看 Code Diff. ,我们做了。
广告:最后,推荐大家上新浪微博@1000copy,这是我的微博。
暗号是:让Code 能够Diff,让Tech也可以Diff。让大家技术成长也分解到每一天的闲言碎语上:)。