一、态度决定一切

1. 做事

  • 应该把重点放到解决问题上,而不是在指责犯错者上面纠缠。

  • 把矛头对准问题的解决办法,而不是人,这是真正有用处的正面效应。

2. 欲速则不达

  • 你必须要理解一块代码是如何工作的,但是不一定需要成为一位专家。只要你能使用它进行有效的工作就足够了,不需要把它当作毕生事业。
  • 如果有一位团队成员宣布,有一块代码其他人都很难看懂,这就意味着任何人(包括原作者)都很难维护它。请让它变得简单些。
  • 不要急于修复一段没能真正理解的代码。这种 +1 / -1 的病症始于无形,但是很快会让代码一团糟。要解决真正的问题,不要治标不治本。
  • 多有的大型系统都非常复杂,因此没有一个人能完全明白所有的代码。除了深入了解你正在开发的那部分代码之外,你还需要从更高的层面来了解大部分代码的功能,这样就可以理解系统各个功能模块之间是如何交互的。
  • 如果系统的代码已经恶化,参考第4点(排除万难,奋勇前进) 。

3. 对事不对人

  • 让我们骄傲的应该是解决了问题,而不是比较出谁的注意更好。
  • 尽力贡献自己的好想法,如果你的想法美欧被采纳也无需生气。不要因为只是想体现自己的想法而对拟定的好思路画蛇添足。
  • 脱离实际的反方观点会使争论变味。若对一个想法有成见,你很容易提出一堆不太可能发生或不太实际的情形去批驳它。这时,请先扪心自问:类似问题以前发生过吗?是否经常发生?
  • 只有更好,没有最好。尽管"最佳实践"这个术语到处在用,但实际上不存在”最佳“,只有在某个特定条件下更好的实践。
  • 不带个人情绪并不是要盲目地接受所有的观点。用合适的词和理由去解释为什么不赞同这个观点或方案,并提出明确的问题。

4. 排除万难,奋勇前进

  • 如果你说天快要塌下来了,但其他团队成员都不赞同。反思一下,也许你是正确的,但是你没有解释清楚自己的理由。

  • 如果你说天快要塌下来了,但其他团队成员都不赞同。认真思考一下,他们也许是对的。

  • 如果设计或代码中出现了奇怪的问题,花时间去理解为什么代码会是这样的。如果你找到了解决办法,但代码仍然令人费解,唯一的解决办法是重构代码,让它可读性更强。如果你没有马上理解这段代码,不要轻易地否定或重写它们。那不是勇气,而是鲁莽。

  • 当你勇敢地站出来时,如果收到了缺乏北京只是的抉择者的抵制,你需要用他们能够听懂的话语表达。”更清晰的代码“是无法打动生意人的。解决资金、获得更好的投资回报,避免诉讼以及增加用户利益,会让论点更有说服力。

  • 如果你在压力下要对代码质量作出妥协,你可以指出,作为一名开发者,你没有职权毁坏公司的资产(所有的代码)。

二、学无止境

5. 跟踪变化

  • 你先不要精通所有技术,但需要清楚知道行业的动向,从而规划你的项目和职业规划。

  • 许多新想法从未变得羽翼丰满,成为有用的技术。即使是大型、热门和资金充裕的项目也会有同样的下场。你要正确把握自己投入的精力。

  • 你不可能精通每一项技术,梅雨哦必要去做这样的尝试。只要你在某一些方面成为专家,就能使用同样的方法,很容易地成功成为新领域的专家。

  • 你要明白为什么需要这项新技术– 它试图解决什么样的问题?它可以被用在什么地方?

  • 避免在一时冲动的情况下,只是一位内想学习而将应用切换到新的技术、框架或开发语言。在做决策之前,你必须评估新技术的优势。开发一个小的原型系统,是对付技术狂热者的一剂良药。

6. 对团队投资

  • 尽量让讲座走进团队
  • 坚持有计划有规律地举行讲座。持续、小步前进才是敏捷。稀少、间隔时间长的马拉松式会议非敏捷也。
  • 不要局限于纯技术的图书和主题,相关的非技术主题也会退对有帮助。

7. 懂得丢弃

  • 要果断丢弃旧习惯,一味遵循过时的就习惯会危害你的职业生涯。
  • 不是完全忘记旧的习惯,而是只在使用适当的技术时使用它。
  • 对所有使用的语言,要总结熟悉的语言特性。并且比较这些特性在新语言或新版本中有什么不同。

8. 打破沙锅问到底

  • 你可能会跑题,问了一些于主题无关的问题。就好比是,如果汽车启动不了,你问是不是轮胎出了问题,者是没有任何帮助的。问“为什么”,但是要问到点子上。
  • 当你问“问什么”的时候,也许会被反问: “为什么你问这个问题?”在提问之前,想好你提问的理由,这会有助于你问出恰当的问题。
  • “这个,我不知道”是一好的起点,应该由此进行更进一步的调查,而不应该嘎然结束。

9. 把握开发节奏

  • 每天结束的时候,测试代码,提交代码,没有残留的代码。
  • 不要搞得经常加班。
  • 以固定、有规律的长度运行迭代。
  • 有规律的开发节奏会暴露很多问题,让你有更多鼓起勇气的借口。
  • 一点点的成功也是一个很大的激励。小而可达到目标会让每个人全速前进。

三、交付用户想要的软件

10. 让客户做决定

  • 记录客户做出的决定,并注明原因。
  • 不要用低级别和没有价值的问题打扰繁忙的业务人员。如果问题对他们业务没有影响,就应该是没有价值的。
  • 不要随意假设低级别的问题不会影响他们的业务。如果能够影响他们的业务,就是有价值的问题。
  • 如果业务负责人回答“我不知道”,这时一个称心如意的答案。也许是他们还没有想那么远,也许是他们只有看到运行的实物才能评估出结果。尽你所能为他们提供建议,实现代码的时候也要考虑可能出现的变化。

11. 让设计指导而不是操纵开发

设计可以分为两层:战略战术。 前期的设计属于战略,通常只有在没有深入理解需求的时候需要这样的设计。良好的战略设计应该扮演地图的角色,指引你向正确的方向前进。任何设计仅是一个起跑点:它就像你的代码一样,在项目的生命周期中,会不停地进一步发展和提炼。

  • “不要在前期做大量的设计”并不是说不要设计。只是说在没有经过真正的代码验证之前,不要陷入太多的设计任务。当对设计一无所知的时候,投入编码也是一种危险的事。如果深入编码只是为了学习或创造原型,只要你随后能把这些代码扔掉,也是一个不错的方法。
  • 即使初始的设计到后面不再管用,你任需设计:设计行为是无价的。在设计过程中学习是有价值的,但设计本身也许没有太大的用处。
  • 白板、草图、便利贴都是非常好的设计工具。复杂的建模工具会让你分散精力,而不是启发你的工作。

12. 合理地使用技术

新技术就应该像是新的工具,可以帮助你更好地工作,它自己不应该成为你的工作。

  • 每一门技术都会有优点和缺点,无论它是开源的还是商业产品、框架、工具或者语言,一定要清楚它的利弊。
  • 不要开发那些你容易下载到的东西。虽然有事要从基础开发所有你需要的东西,但那是相当危险和昂贵的。

13. 保持可以发布

14. 提早集成,频繁集成

  • 成功的集成意味着所有的单元测试不停地通过。

15. 提早实现自动化部署

16. 使用演示获得频繁反馈

17. 使用短迭代,增量发布

迭代开发是,在小且重复的周期里,完成各种开发任务:分析、设计、实现、测试和获得反馈,所以叫迭代。

增量开发:发布带有最小却可用功能块的产品。

18. 固定的价格就意味着背叛承诺

基于真实工作的评估。让团队和客户一起,真正地在当前项目中工作,做具体实际的评估。由客户控制他们要的功能和预算。

四、敏捷反馈

19. 守护天使

  • 单元测试是优质股,值得投资。但一些简单的属性访问方法或者价值不大的方法,是不值得花费时间进行测试的。
  • 人们不编写单元测试的很多借口都是因为代码中的设计缺陷。通常,抗议越强烈,就说明设计越糟糕。
  • 单元测试只有在达到一定测试覆盖率的时候,才能真正发挥作用。
  • 不是测试越多质量就越高,测试必须要有效。
写单测的理由
  • 单元测试能及时提供反馈
  • 单元测试让你的代码更加健壮
  • 单元测试是有用的设计工具
  • 单元测试是让你自信的后台
  • 单元测试是解决问题时的探测器
  • 单元测试是可信的文档
  • 单元测试是学习工具

20. 先用它再实现它

使用被称为 TDD(Test Driven Development, 测试驱动开发)的技术,你总是在有一个失败的单元测试后才开始编码。将 TDD 作为设计工具,它会为你带来更简单更有效的设计。

  • 不要把测试优先和提交代码之前的测试等同起来。测试先行可以帮助你改进设计,但是你还是要在提交代码之前做测试。
  • 任何一个设计都可以被改进。
  • 单纯的单元测试无法保证好的设计,但它们会对设计有帮助,会让设计更加简单。

21. 不同环境,就会有不同问题

使用持续集成工具,在每一种支持的平台和环境中运行单元测试。要积极地寻找问题,而不是等问题来找你。

22. 自动验收测试

为核心的业务逻辑创建测试。

23. 度量真实的进度

度量剩下的工作量。不要用不恰当的度量来欺骗自己或者团队,要评估那些需要完成的待办事项。

  • 关注功能,而不是日程表。

24. 倾听用户的声音

  • 没有愚蠢的用户。
  • 只有愚蠢、自大的开发人员。
  • “它就是这样的。”这不是一个好的答案。
  • 如果代码问题解决不了,也许可以考虑通过修改文档或者培训来弥补。
  • 你的用户有可能会阅读所有的文档,记住其中的所有内容。但也可能不会。

五、敏捷编码

25. 代码要清晰地表达意图

编写清晰的而不是讨巧的代码。向代码阅读者明确表明你的意图。可读性差的代码一点都不聪明。

应该让自己或团队的其他任何人,可以读懂自己一年前写的代码,而且只读一遍就知道它的运行机制。

26. 用代码沟通

DRY 原则 (Don’t Repeat Youreself) .

建立代码文档无外乎两种方式:利用代码本身;利用注释来沟通代码之外的问题。

使用细心挑选的名称和清晰的执行路径,代码几乎不需要注释。代码能够自解释,而不用以来注释,是一件很好的事情。

注释可用来为读者指定一条正确的代码访问路线图。为代码中的每个类或模块添加一个短小的描述,说明其目的以及是否有任何特别需求。对于类中的每个方法,可能要说明下列信息

  • 目的: 为什么需要这个方法?
  • 需求(前置条件):方法需要什么样的输入,对象必须处于何种状态,才能让这个方法工作?
  • 承诺(后置条件):方法成功执行后,对象现在处于什么状态,有那些返回值?
  • 异常:可能会发生什么样的问题?会抛出什么样的异常?

用注释沟通:使用细心选择的、有意义的命名。用注释描述代码意图和约束。注释不能替代优秀的代码。

  • 在代码可以传递意图的地方不要使用注释。
  • 解释代码做了什么的注释用处不那么大。相反,注释要说明为什么会这样写代码。
  • 当重写方法时,保留描述原有方法意图和约束的注释。

27. 动态评估取舍

考虑性能、便利性、生产力、成本和上市时间。如果性能表现足够了,就将注意力放到其它因素上,不要为了感觉上的性能提升或者设计的油烟,而将设计复杂化。

  • 如果现在投入额外的资源和精力,是为了将来可能得到的好处,要确认投入一定要得到汇报。
  • 真正的高性能系统,从一开始设计时就在向这个方向努力。
  • 过早的优化时万恶之源。
  • 过去用过的解决方案对当前的问题可能适用,也可能不适用。不要事先预设结论,先看看现在时什么情况。

28. 增量式编程

29. 保持简单

  • 代码几乎总时可以得到进一步精炼,但时到了某个点之后,再做改进就不会带来任何实质性的好处了。这时开发人员就应该停下来,去做其他方面的工作了。
  • 要将目标牢记在心:简单、可读性高的代码。强行让代码变得优雅与过早优化类似,同样会产生恶劣的影响。

30. 编写内聚的代码

让类的功能尽量集中,让组件尽量小。要避免创建很大的类或组件,也不要创建无所不包的大杂烩类。

31. 告知,不要询问

不要抢别的对象或是组件的公工作。告诉它做什么,然后盯着你自己的职责就好了。

32. 根据契约进行替换

里氏代换原则(Liskov Substitution Principle LSP)面向对象设计的基本原则之一。

  • 相对继承来说,委托更加灵活,适应力也更强。
  • 继承不是魔鬼,只是长久以来被大家误解了。
  • 如果你不确定一个接口做出了什么样的承诺,或者有什么样的需求,那就很难提供一个对其有意义的实现了。

六、敏捷调试

33. 记录问题解决日志

34. 警告就是错误

签入带有警告的代码,就跟签入有错误或者没有通过测试的代码一样,都是极差的做法。签入结构工具中的代码不应该产生任何警告信息。

35. 对问题各个击破

在解决问题时,要将问题域与其周边隔离开,特别时在大型应用中。

36. 报告所有的异常

  • 决定由谁来负责处理异常时设计工作的一部分。
  • 不是所有的问题都应该抛出异常。
  • 报告的异常应该在代码的上下文中有实际意义。
  • 要传播不能处理的异常。

37. 提供有用的错误信息

  • 区分错误类型
    • 程序缺陷
    • 环境问题
    • 用户错误

七、敏捷协作

38. 定期安排会面时间

使用立会:立会可以让团队达成共识,保证会议短小精悍不跑题。

39. 架构师必须写代码

优秀的设计从积极的程序员那里开始演化。积极的编程可以带来深入的理解。不要使用不愿意编程的架构师—- 不知道系统的真实情况,是无法展开设计的。

  • 不要允许任何人单独进行设计,特别时你自己
  • 如果有有个首席架构师,他可能没有组足够的时间来参与编码工作。还是要让他参与,但是别让他开发在项目关键路径上的、工作量最大的代码。

40. 实际代码集体所有制

让开发人员轮换完成系统不同领域中不同模块的不同任务。

  • 代码集体所有制并不意味着可以随心所欲,到处破坏。

41. 成为指导者

  • 如果一直在就同一个主题向不同的人反复阐述,不放记录笔记,此后就此主题写一篇文章,甚至是一本书。
  • 成为指导者时向团队进行投资的一种极佳的方式。
  • 结对编程时一种进行高效指导的、很自然的环境。

42. 允许大家自己想办法

指给他们正确的方向,而不是直接提供解决方案。每个人都能从中学到不少东西。

  • 用问题来回答问题,可以引导提问的人走上正确的道路。
  • 如果有人真的陷入胶着状态,就不要折磨他们了。告诉他们答案,再解释为什么时这样。

43. 准备好后再共享代码

绝不要提交尚未完成的代码。

44. 做代码复查

对于提升代码质量和降低错误率来说,代码复查时无价之宝。如果以正确的方式进行,复查可以产生非常实用而高效的成果。要让不同的开发人员在每个任务完成后复查代码。

45. 及时通报进展与问题

发布进展状态、新的想法和目前正在关注的主题。不要等着让别人来问项目状态如何。