最近项目上做了一个看起来既不是story也不是bug的东西。可以定性为一个tech story。这件事情看起来很简单,但是后来被证明涉及到了系统的太多地方,做的非常艰难,在认为做完之后,不但fail了一堆test,而且引入很多bug。又花了很多时间去修。就这些问题做下总结。
1,刚开始写这个sotry的时候,由于缺乏对系统的整体认识,低估了复杂度。虽然我也把问题进行了细化,但是对每个问题都没有去估计其复杂度和它会涉及到的部分。即使对系统不够熟悉,也应该先花点时间,通过IDE对代码的分析功能,比如查找reference等,对每个细化了的子问题进行分析,从而尽量避免bug的引入。
2,关于test。我觉得没有完成的功能不能提交到svn,所以积累了很长时间的一次提交导致了很多tests fail了。花了几个小时来修test。这里就体现出了test要频繁运行的重要性。尤其是像这种对整个系统很多方面都又影响的变化。通过频繁运行test,可以在做一点修改之后就发现问题所在,fail的也会比较少,所以修起来就比较容易。事实上由于我没有频繁运行test,最后一下子fail了70个...
3,说到本地运行test没有频繁运行,事实上是本地根本就没有运行。因为我们工作在一个遗留系统上,原始的测试框架都不是我们自己搭建的,在试图本地运行的时候,总是存在一些配置的问题。所以没能及时的运行测试。
4,那么为什么不能花点时间把本地环境搞好呢。原因就很多了。包括硬件的问题,软件的问题,还有花费的代价的问题。如果在客户付钱的时间里做这些事情,而且无法估计要花多少时间来完成,那就是很冒险的事情了。很可能做了几天都没什么结果。所以注定这些事情只能在工作之外的时间做,通俗讲就是加班。虽然不是为了进度而加班,但到底还是加班了。这个就看个人意愿了。这时想到一个同事说过的一句话:“一个有责任心的人到哪里都会加班的”。
5,关于修改代码时的策略。应该首先以满足功能为原则,对于有可能影响很多地方的重构,要谨慎进行。比如这里我修改了一个Java实体类的映射字段名字,虽然使用了IDE的重构功能把很多相关的地方都改掉了。但是总还是有些死角。比如在Hibernate里面的HQL,IDE就不可能这么强大的能把这些地方修改过来。所以还是必须先完成功能,保证测试没有fail掉,然后再去做重构,这样比较合理。
6,再提测试,不过是另外一个问题。再测试驱动开发里,提倡测试即文档,也就是说测试就描述了产品代码的行为。事实上我做的这个修改有很大一部分就是修改产品行为。正常的做法是先修改测试,然后修改产品代码使其通过测试。如果对代码库很熟悉,这样做还算是得心应手。但是事实上是不怎么熟悉,这种情况下,也可以这么做,但是比较困难,而且无法保证完全修改到,但是关系不大,做完产品代码的修改后,一运行测试就知道有什么问题了。然后就是修test,对于很多的test,修改的方法就是改变assert里面的expectedValue...这样看起来就很无聊了,不过细想想,其代码不算很大,而且还是很有价值的。
7,还有心态的问题。由于一开始没有对问题分析好,导致走错的方向,浪费了时间。然后就着急了。虽然自己主动加班,但是由于心里比较急躁,加上做事方法的问题,越做越糟,最后还拖了队友一起加班到深夜...真是不好意思。
8,在做事情的时候要有自己的主线,如果在开发的过程中发现了其他的相关的问题或者bug,不能因此而分心,记录下来,在做完了主线之后再去考虑这些新发现的问题,是顺手做了,还是新建一个任务。如果看到其他问题就分心去做,那么很快就会迷失在问题的迷宫里了。
9,其实做到底还是做事经验的积累和做事能力的提高。这样才能游刃有余的做事。
最后总结一下,做事前先把问题细化,分析复杂度,修改每一行代码都要好好考虑它可能的引起的影响,频繁运行测试。然后就是努力提高能力了。