一. 态度
敏捷依赖人,而不是依赖于项目的甘特图和里程表。因此态度非常重要,包括你的和团队的。专业的态度应该着眼于项目和团队的积极结果,关注个人和团队的成长,围绕最后的成功开展工作。由于很容易变成追求不太重要的目标,所以在本章,我们会专注于那些真正的目标。集中精力,你是为做事而工作。
1. 做事
指责不修复bug,出了问题第一优先级应该是解决问题,不要抱怨指责他人。
2. 欲速则不达
偷懒、耍小聪明、不深入了解真正的问题以及可能的后果,就快速修改代码,只是解决表面问题最终会引发大问题。
千里之堤,溃于蚁穴,大灾难是逐步演化来的。一次又一次的快速修复,每一次都不探究问题的根源,久而久之就形成了一个危险的沼泽地,最终会吞噬整个项目的生命。
3. 对事不对人
真诚、虚心的讨论问题,引导性的提出一个疑问,让他们自己意识到问题。
4. 排除万难,奋勇前进
当发现问题时,不要试图掩盖问题。
重写糟糕代码,并比较重写前后的优缺点。
二. 学习
即使你已经在正确的轨道上,但如果只是停止不前,也仍然会被淘汰出局。
5. 跟踪变化
技术快速更新迭代,作为技术人需要持续迭代更新自己的知识,需要了解行情,需要如饥似渴的阅读。
6. 对团队投资
个人技术好远远不够,一个学习型的团队才是较好的团队。
7. 懂得丢弃
变化是永恒的,我们学习新技术和新方法。但是记住,你也需要学会如何丢弃。
8. 打破砂锅问到底
不断追问了解问题的本质。
9. 把握开发节奏
管理好自己的时间,养成习惯,不要加班并在下班前完成当天的工作。
三. 交付
10. 让客户做决定
用业务负责人能够理解的语言,向他们详细解释遇到的问题,并让他们做决定。
11. 让设计指导而不是操纵开发
设计满足实现即可,不必过于详细。即使之前已经提交了设计文档,也还会有一些意料之外的情况出现。
12. 合理地使用技术
盲目地为项目选择技术框架,就好比是为了少交税而生孩子。
确保技术能解决你的问题、考虑可取消性(一些技术是贼船,一旦你使用了它,就会被它套牢,再也不可能回头了)、维护成本。
13. 保持可以发布
持续集成和版本管理确定已提交的代码应该随时可以发布。
14. 提早集成,频繁集成
集成有风险,特别是多人协同开发时。应该尽早开始持续有规律的集成来规避风险。
15. 提早实现自动化部署
16. 使用演示获得频繁反馈
需求就像是流动着的油墨。
17. 使用短迭代,增量发布
每个增量开发中,使用1~4周左右迭代周期。
18. 固定的价格就意味着背叛承诺
软件项目会遭遇各种各样的小错误,还要加上基础需求的变化,估算应该基于实际的工作不断变化。
四. 反馈
很多项目,都是因为程序代码失控而陷入困境。修复bug导致了更多的bug,从而又导致了更多的bug修复,成堆的测试卡片最后会把项目压垮。
19. 守护天使
单元测试是你的守护天使
20. 先用它再实现它
如果要让你的产品尽可能地好,自己先要积极地使用它。
21. 不同环境,就有不同问题
要重视多平台问题(大部分场景已经可以通过 docker 来解决)
22. 自动验收测试
核心业务需要编写单元测试
23. 度量真实的进度
判断工作进度最好是看实际花费的时间而不是估计的时间。
24. 倾听用户的声音
我们花费了很大的精力从单元测试之类的代码中获得反馈,但却容易忽略最终用户的反馈。
不仅需要和真实用户进行交谈,还需要耐心地倾听。
五. 编码
任何一个笨蛋都能够让事情变得越来越笨重、越来越复杂、越来越极端。——John Dryden
新项目刚开始着手开发时,它的代码很容易理解和上手。然而,随着开发过程的推进,项目不知不觉中演变为一个庞然怪物。发展到最后,往往需要投入更多的精力、人力和物力来让它继续下去。
开始看起来非常正常的项目,是什么让它最终变得难以掌控?
开发人员在完成任务时,可能会难以抵挡诱惑为节省时间而走“捷径”。然而,这些“捷径”往往只会推迟问题的爆发时间,而不是把它彻底解决掉。当项目时间上的压力增加时,问题最终还是会在项目团队面前出现,让大家心烦意乱。
25. 代码要清晰地表达意图
代码阅读的次数要远远超过编写的次数,代码清晰程度的优先级应该排在执行效率之前
写下一行代码只要1分钟,但未来会被阅读很多次、改很多次。代码的可读性与可维护性,是我心目中好代码的第一标准。——鲁肃
26. 用代码沟通
代码就是最好的注释,同时也是最好的文档。
通常程序员都很讨厌写文档。这是因为大部分文档都与代码没有关系,并且越来越难以保证其符合目前的最新状况。这不只违反了DRY原则(不要重复你自己,Don’t Repeat Yourself,见[HT00]),还会产生使人误解的文档,这还不如没有文档。
27. 动态评估取舍
没有适宜所有状况的最佳解决方案。你必须对手上的问题进行评估,并选出最合适的解决方案。每个设计都是针对特定问题的——只有明确地进行评估和权衡,才能得出更好的解决方案。
考虑性能、便利性、生产力、成本和上市时间。如果性能表现足够了,就将注意力放在其他因素上。不要为了感觉上的性能提升或者设计的优雅,而将设计复杂化。
28. 增量式编程
增量式编程可以精炼并结构化你的代码。代码被复杂化、变成一团乱麻的几率减少了
29. 保持简单
相比一个过分复杂、拙劣的解决方案,简单的方案通常更难以获得。
我们要充分认识到做产品,复杂性是真正的敌人!
30. 编写内聚的代码
如果一个类(或者一个组件)变化得过于频繁,这样的改变会对整个系统形成“涟漪效应”,并导致更多的维护和成本的发生。
31. 告知,不要询问
不要抢别的对象或是组件的工作。告诉它做什么,然后盯着你自己的职责就好了。
将命令与查询分离开来
David Bock使用“送报男孩和钱包的故事”很好地诠释了这一点。①假定送报男孩来到你的门前,要求付给他本周的报酬。你转过身去,让送报男孩从你的后屁股兜里掏出钱包,并且从中拿走两美元(你希望是这么多),再把钱包放回去。然后,送报男孩就会开着他崭新的美洲豹汽车扬长而去了。
在这个过程中,送报男孩作为“调用者”,应该告诉客户付他两美元。他不能探询客户的财务状况,或是钱包的薄厚,他也不能代替客户做任何决策。这都是客户的责任,而不属于送报男孩。敏捷代码也应该以同样的方式工作。
32. 根据契约进行替换
当使用继承时,要想想派生类是否可以替换基类。如果答案是不能,就要问问自己为什么要使用继承。
六. 调试
即使是运作得最好的敏捷项目,也会发生错误。bug、错误、缺陷——不管被称作什么,它们总会发生。
33. 记录问题解决日志
维护一个问题及其解决方案的日志 。保留解决方案是修复问题过程的一部分,以后发生相同或类似问题时,就可以很快找到并使用了。
34. 警告就是错误
将警告视为错误 。签入带有警告的代码,就跟签入有错误或者没有通过测试的代码一样,都是极差的做法。签入构建工具中的代码不应该产生任何警告信息。
35. 对问题各个击破
识别复杂问题的第一步,是将它们分离出来。
分离应该从设计阶段开始,并贯穿软件开发整个生命周期。
36. 报告所有的异常
处理或是向上传播所有的异常 。不要将它们压制不管,就算是临时这样做也不行。在写代码时要估计到会发生的问题。
37. 提供有用的错误信息
提供更易于查找错误细节的方式。发生问题时,要展示出尽量多的支持细节,不过别让用户陷入其中。
七. 协作
高效的协作是敏捷开发的基石
38. 定期安排会面时间
立会可以让团队达成共识。保证会议短小精焊不跑题。
采取立会的形式需要管理层的承诺和参与。
39. 架构师必须写代码
系统的设计者必须要亲自投入到实现中去。
一个真正的架构师“……应该指导开发团队,提升他们的水平,以解决更为复杂的问题”。
Martin Fowler: https://www.martinfowler.com/ieeesoftware/whoNeedsArchitect.pdf
40. 实行代码集体所有制
让开发人员轮换完成系统不同领域中不同模块的不同任务。
需要忍受一段时间内的效率的降低。但是眼光放长远一点,有好几双眼睛盯着某一段代码,是一定可以带来好处的。这样可以提升代码的整体质量,使其易于维护和理解,并降低出错率。
41. 成为指导者
教学相长,通过详细解释自己知道的东西,可以使自己的理解更深入。
分享自己的知识很有趣——付出的同时便有收获。还可以激励别人获得更好的成果,而且提升了整个团队的实力。
42. 允许大家自己想办法
比解决问题更重要的是帮助他人学会如何解决问题。指给他们正确的方向,而不是直接提供解决方案。每个人都能从中学到不少东西。
授人以鱼,三餐之需;授人以渔,终生之用。
43. 准备好后再共享代码
绝不要提交尚未完成的代码。
44. 做代码复查
要寻找深藏不露的程序bug,正式地进行代码检查,其效果是任何已知形式测试的两倍,而且是移除80%缺陷的唯一已知方法。——Capers Jones的《估算软件成本》
45. 及时通报进展与问题
发布进展状况、新的想法和目前正在关注的主题。不要等着别人来问项目状态如何。
八. 走向敏捷
只要一个新的习惯
只要一个新的习惯,就让团队发生巨大的变化。
通过一些规矩保证例会的举行,并很快形成习惯。从例会开始让团队有机会进行彼此讨论,并对重大问题达成共识。
确保例会真的有用,团队一起讨论项目,同步信息并看到新的希望!
拯救濒临失败的项目
对一个已经处于困境的项目,突然改变这个项目的全部开发习惯,是让项目突然死亡的最佳方式。
当项目岌岌可危时,应该先引入一系列习惯来稳定目前的状况。
管理者指南
管理者有责任让整个团队知道接下来将要发生什么。要向大家说明敏捷开发是要让开发人员的工作变得更加轻松 ,这主要是为了他们好。如果没有达到这样的效果,那就是有些地方出了问题。
要慢慢来,领导所做的每一个小动作,都会随着时间对团队产生巨大的影响。
入门级习惯:版本控制、单元测试、自动构建
程序员指南
如果要将团队带入新的领域,必须首先以身作则。
从单元测试开始是一个不错的选择。可以先针对自己的代码开始使用。
九. 其他
推荐配合阅读
《程序员修炼之道》 —— David Thomas / Andrew Hunt
《重构 : 改善既有代码的设计》——Martin Fowler
《代码整洁之道、架构整洁之道》——Robert C. Martin