头看,我们还是认为就算当初花几倍的时间去做设计,也难免犯同样的 错误。其次,检验设计优劣的最佳工具就是代码本身,及早地应用
设计于代 码,让代码来 告诉你设计正确与否。这正是在这个 story 陷入泥沼时我们的反应:实现不能继续,来看
看 设计的问题吧。再次,之后我们的设计之所以如此成功 地符合了业务的需求,是因为前一 次失败的经历让我们对代码有了更进一步的了解, 对问题有了更清晰的洞察。 谜团是在行进 中解开的,并不是一开始就能知晓。最 后,我想我们唯一应该改进的,就是在发现开发出 现困难时,能更早地跳出来,从设计角度分析一下
问题。 新的设计实现能在一个下午完成, 因为高测试覆盖率为正确的重构实施提供了安全保障。 是 测试总能迅速地提醒我们哪些地方出了错,以保证重构的正确。其次,良好的代码结构,也 是代码能如此快速 地修改完成的原因。这些都是 TDD 带来的好处,TDD 不仅能提供高测 试覆盖率,也能带来良好的代码设计。这就是越来越多的人把 TDD 称之为测试驱动设计 (Test-Driven Design)的原因。 TDD 给设计带来的一些好处: ● TDD 迫使你在编写代码之前,考虑更多对象之间的交互。 ● TDD 迫使你把对象的创建封装在一个更好的层次上。 ● TDD 会让你写出更加小而内聚的方法, 从而使方法的重用以及纠错变得更加方便、 快速。 百倍加速——关键字:性能,重构,YAGNI 关键字:性能,重构, 百倍加速 关键字 随 着项目进入后期,功能的开发已经基本完成。此时,我们面临系统的性能问题:发布一 个标准竟然要 5 个小时,令人无法忍受。由于发布标准需要在一个事务内完 成,而且要修 改大量数据。所以在这 5 个小时内,数据库的很多表都被锁定,系统几乎处于瘫痪状态。于 是,顶着巨大的压力,我们开始了性能优化之旅。
先通过添加日志找出最耗时的操作, 然后仔细跟踪和分析这块代码。 我们随即发现了一个耗 2 时十分钟的操作,这个方法的时间复杂度是 n 。 但这段代码犯了一个低级错误,它可以 被优化成一个 n 复杂度的方法。立即修改,修改后由于消除了大量重复操作,它的耗时竟 然不超过一秒。“秒杀十分钟”就这 样诞生了。随着我们进一步的跟踪和分析,多处设计上 的问题暴露出来。几天的改进之后, 5 个小时的操作缩减到了 1 个小时。 但显然,一个 小时的操作还是不能为客户所接受的。于是,继续优化。马上,我们就发现 标准发布操作对很多标准都进行了重新算分,但实际上只需对有改动的标准算分即可。而 没有改动的标准,可以把它的得分结果存于数据库,下次用到时从数据库读取即可。通过这 个“缓存”,我们再次大大提升了速度。运行之,整个操作竟然只需 5 分 钟!5 个小时的操 作,到现在的 5 分钟,百倍加速也! 这个性能优化问题是个典型案例,它给了我们很多启示。首先,在遇到性能
问题时,先别 忙着埋怨平台的速度,还是先看看设计里面存在的问题吧。其次,也是我们可以改进的一点 是:在 TDD“红-绿-重构”的标准开发节奏中,如果我们多花一点时 间在“绿”之后进行重构, 就可以避免犯一些低级错误。 或许有人会说,如果你在刚开始就做更多的设计,就能避免到最后出现这样的性能问 题。 但我想说,非也,你忘了:你将不需要它(YAGNI)。预想开发是个迷人的陷阱,或许可以 在刚开始就花费十倍的时间去避免这个性能问题的产生。但问题 时,在刚开始你怎么知道 哪些是必要的设计, 而哪些是浪费呢?敏捷团队注重的是给客户创造真正有价值的业务, 而 不是花费大量时间去制造一个“华而不实”的系 统。 “只在确实需要时才提供功能”,这是我们遵循的准则。 最后,性能改进之所以如此顺利,得益于我们遵循的一些敏捷 实践。比如 TDD 带来的高测 试覆盖率,保证了重构的正确性。在 BOSCO 项目的开发中,不乏这样的大型重构,我们从 不害怕修改代码,因为有坚实的测试代码 为重构撑起了安全网。而反之,重构促进了代码 结构的优化,提升了系统性能。 从这两个问题我们可以看到: ● 敏捷实践促进了系统设计的灵活,代码结构的优化,系统质量的提升。 ● 各项敏捷实践之间其实是相辅相成,相互促进的。 BOSCO 脚印 通过对 BOSCO 系统代码的统计数据,我们可以看到: ● 代码设计的优良:平均每个类不超过十个方法,每个方法不超过五行代码。如果除去特 殊的 Helpers 模块,平均每个类不超过 7 个方法。 ● 高测试覆盖率:测试代码与功能代码的比例是 1.5:1,行覆盖率达到 90%以上。
● 开发人员的熟练度: 每对 pair 每天 6 次的提交速度足以证明开发团队对于系统的熟悉度。 由于 Ruby On Rails 是一个特别擅长开发 Web 应用的框架, 考虑到其所具备的强大表现力, 我们相信此系统的复杂度不亚于很多规模在十多万行代码的系统。 TimeMachine.go_to("2008-09-17") 时 间定格在 BOSCO 项目第三次发布的那一天。除了需要一段时间的 bug 修复和数据准备 之外,发布并没有给工作带来太多不同。我们从未因为发布的到来而惊 慌,也从未在发布 时忙得不可开交。正如团队一成员所说,每次我们都是在等待发布,安静地等待着发布的到 来。因为合理的安排和控制,让一切尽在掌握中。 发布成功,欢呼之余,让我们回头看看项目中的哪些实践保障了发布的顺利完成吧。 客户协作——关键字:PM、BA,还有 Dev 关键字: 客户协作 关键字 、 , 曾 经有一个同事突发感想说:“在