敏捷开发是指在一个高度协作的环境中,不断的使用反馈进行自我调整和完善。
过程符合标准,但结果不一定是正确的。敏捷更关注与结果
过程符合标准,但结果不一定是正确的。敏捷更关注与结果
先难后易. 我们首先要解决困难的问题, 把简单的问题放到最后.
1 指责不会修复BUG. 面对问题最先要考虑的是解决问题,而不是追究责任
2 不要追求快速的简单修复.要投入时间和精力去保持代码的整洁,敞亮
深入了解自己正在开发的那部分代码,从更高层面上了解系统中其他部分的代码,理解各个功能模块间是如何交互的
3 对事不对人,让我们骄傲的应该是解决了问题,而不是谁提出的方案
在开始寻求最好的解决方案之前,大家要对“最好”先达成一致,在开发者眼中最好的在用户看来可能不是,反之亦然
4 做正确的事,要诚实,有勇气的说出实情。但之前要确定自己看到了全部的实情,不然就不是勇敢而是鲁莽
5. 跟踪技术变化. 你不需要精通所有技术, 但需要清楚知道行业的动向, 从而规划你的项目和职业生涯.如果必须要把工作切换到一种新的技术领域, 可以不费大多时间做到
如果你是团队中最好的队员, 就没有动力继续提高自己. 如果周围的人都比你厉害, 你就会有很强的动力去追赶他们. 你将会在这种游戏中走向自己的顶峰.
6. 提供你和团队学习更好的平台. 午餐会议. 不是设计会议. 应该专注讨论一些与应用相关的一般性主题. 而具体的设计问题, 最好留在设计会议中去解决
优秀的管理者会重用那些能提高其他团队成员价值的人.
7. 拥抱变化. 掌握新方法的时候, 要舍弃就方法. 新技术会让人感到有点恐惧. 你确实需要学习很多东西. 已有的技能和习惯为你打下了很好的基础. 但不能依赖他们
过去电脑和CPU是昂贵的资源, 但现在开发者的时间才是紧缺和昂贵的资源.
学习新的语言, 新的技术, 不能把太多旧的态度,方法和思维用在新技术上. 但不是要完全摒弃旧的方法, 起码要保证, 不能习惯性的落入旧习惯旧思维. 否则, 你辛苦学习一门新的语言, 就失去了期望获得的益处
对于所使用的语言, 要总结熟悉的语言特性, 并且比较这些特性在新语言或者新版本中有什么不同
8. 不停的问为什么. 不能只满足于别人告诉你的表面现象. 要不停的提问知道你明白问题的根源
问为什么之前要想好你提问的理由, 这会有助于你提出恰当的问题
9. 保持迭代的时间间隔固定,但可以修改迭代的功能点。稳定多次的迭代会给人以鼓励和信心. 展示给用户可以使用的软件
10. 让真正使用软件的客户做决定,而不是开发者。不要让低级别和没有价值的问题影响客户,判断的标准是这个问题会不会影响到业务
11 让设计指导而不是操纵开发。好的设计是正确的,但不是精确的。不应该涉及到不确定的问题
12. 要合理的使用技术. 我们选择技术是为了解决问题, 而不是为了体验新框架. 所以首先要明确我们需要解决的问题, 在去评估技术方案. 任何技术方案都是有利弊的, 新技术就像是工具, 它可以使我们更好的工作, 它本身不应该成为工作内容
13 保持可发布. 通过分支, 规范代码提交等方法实现系统随时可编译发布, 并随时演示给用户. 这样才可以及时收到用户的反馈
14. 代码集成是很大的一块风险区, 所以应该提早集成, 频繁集成
15. 提早实现自动化部署, 让系统可以自动,方便,快速,完整的部署到用户的服务器上
16. 需求总是在变, 要保持应用可见, 每隔一段时间邀请所有用户, 频繁地给用户演示可以获取频繁的反馈, 就可以让软件更贴近用户的期望. 但要避免拿不能用或者缺少功能的版本演示, 这样只会让用户觉得愤怒
17. 增量开发. 发布带有最小却可用功能块的产品. 每个增量开发中, 使用1~4周左右迭代周期
18. 对于固定价格的应用开发,可以尝试的方法
1. 主动提议先构建系统最初的, 小的有用的部分. 挑选一系列小的功能,这样完成一次交付应该不大于6~8周. 但要能让用户真正使用
2. 一个迭代结束以后, 用户有两个选择. 一是选择一系列新功能,继续下一个迭代; 而是取消合同, 仅需支付第一个迭代几周的费用
3. 如果用户继续, 后面的迭代也是可供用户随时停止而不需要缴纳违约金. 他们甚至可以控制每个迭代的功能点, 这样从客户的角度来看, 他们可以更大程度的对项目进行掌控. 对他们而言, 降低了风险.
19. 使用自动化单元测试, 好的单元测试能够为你的代码问题提供及时的警报. 如果没有到位的单元测试, 不要进行任何设计和代码修改. 但单元测试要达到一定的测试覆盖率才会真正起作用
可以选择标准的测试框架, 如java的JUnit, webservice的HttpUnit等, 并让他们可以自动运行. 就像IDE的自动编译一样, 每次修改代码以后, 就会自动的进行单元测试, 来确保新修改的代码不会影响已有的功能. 这一步要做的事情, 就是在后台架设一个构建机器, 不断的获取最新版本的代码, 然后编译, 并进行单元测试, 有任何错误及时通知开发人员.
推荐书籍:<单元测试之道>,<项目自动化之道>
单元测试可以及时提供反馈, 符合敏捷开发中要持续获取反馈并完善优化的要求. 另外, 单元测试是有用的设计工具, 可信的文档以及学习的工具
20. 先用它再实现它. 也就是TDD(测试驱动开发), 会为你带来更简单有效的设计. 使你可以更加专注于设计接口, 而不会被太多实现的细节所干扰.
不要把测试优先和提交代码之前的测试等同起来.
21. 不同环境就有不同问题. 有了单元测试, 和自动持续集成构建的工具, 还需要在不同的环境中进行部署, 来警示不同操作系统不同环境下是否正常
22. 自动验收测试. FIT工具. 将对比正确结果与系统运算结果对比等这种需要人工的操作自动化.
23. 度量真实的进度. 不要使用不恰当的度量来欺骗自己或者团队, 或许这种很笼统的进度数据是用户需要的, 但它并不适用于开发团队内部. 要度量那些需要完成的待办事项.
24 编写清晰而不是讨巧的代码,代码的可读性要高于执行效率
25. 并不是注释多就是好的,注释多说明代码可读性差。好的代码应该是包含文档内容的,优雅而清晰简洁。代码自解释。
注释应该包含意图,期待结果,应该注意的地方。代码的逻辑及实现原理应该更多的从代码中获取。
26. 使用细心选择的有意义的命名,用注释描述代码意图和约束,注释不能代替优秀的代码。解释代码做了什么的注释用处并不大,注释要说明为什么这么写代码
27. 考虑性能,便利性,生产力,成本,上市时间。不要为了感觉上的性能提升和设计的优雅而将设计复杂化。过早的优化是万恶之源
28. 采用增量编程和测试,使用 测试优先的方式开发。关键在于持续做一些细小而有用的事情,而不是做一段长时间的编程和重构。这就是敏捷的方式
29. 开发可以工作的最简单的解决方案,除非有不可辩驳的原因,否则不要使用模式,原则和高难度技术之类的东西。但另一方面强行让代码变得优雅和过早的优化都会产生恶劣的影响
30. 高内聚。让类的功能尽可能的集中,让组件尽量小。要避免创建大的类和组件,不要创建无所不包的类
31. 告知不要询问。告诉他要做什么,然后继续自己的流程,而不是抢他的工作,由自己来决策。就是说,由自己来发消息而不是调用函数
面向过程的代码获取信息然后决策,面向对象的代码让别的代码去做事情。作为某段代码的调用者,开发人员不应该基于被调用对象的状态来做决策,更不能改变该对象的状态,这样的逻辑应该是被调用对象本身的,而不是你的责任。在对象之外替他做决策就会违反他的封装性
命令和查询分开,就是把功能和方法按照命令和查询分开存放。命令是指会产生内部影响的方法,查询没有副作用,尽提供给外部对象的状态而不会修改。
32. 通过替换代码来实现系统扩展。通过替换遵循接口契约的类,来添加并改进功能特性。多使用委托而不是继承。
继承和委托分别适用于什么情况下呢。
如果新类可以替换已有的类,并且他们之间的关系可以用is_a来描述,就使用继承。如果新类只是使用已有的类,并且两者之间的关系是has_a 或者uses_a ,就使用委托。这里的委托就是指聚合。
33. 维护一个问题及解决方案的日志。模板参考
问题发生时间;问题简述;解决方案详细描述;引用文章或网址提供更多信息和细节;任何代码片段,设置,对话框截屏等,有利于更加深入理解的细节
34. 将警告视为错误。
35. 隔离问题,将问题各个击破。识别复杂问题的第一步就是把他们分离出来,将问题域和周边分隔开
36. 处理或者向上抛出异常,不要自己捕获了但又不处理
37. 展示有用的错误信息,提供更易于查找错误的方式。发生问题时要展示出更多的支持细节,但不要让用户陷入其中。
建议的方法:将异常信息用链接方式隐藏;将异常信息由用户触发发送给系统后台;将系统异常日志做成rss feed;异常信息除了异常堆栈还应该包含当时的系统和用户快照;没有必要等待抛出异常才发现问题,可以使用断言;提供给用户的信息可以包含一个主键,以便定位日志位置
38. 使用立会可以使团队成员达成共识,但要保证会议短小精悍。
每个人只回答3个问题;在上班后的半个小时到一个小时之后。参与者只有开发者和团队直接管理者;立会时间不能超过30分钟。小团队可以两天或一周一次;要报告工作的细节
39. 优秀的设计从积极的程序员那里开始演化。积极的编程可以带来深入的理解。不要使用不愿意编程的架构师。
架构,设计,编码,测试彼此是不可分割的。如果架构师没有足够的时间来编码,可以让他不做正在进行的或工作量大的代码。不要允许任何人单独进行设计,特别是你自己
作为设计人员,只通过一些高度概括的粗略的设计图是无法了解系统的,更要深入到系统的具体细节中
40. 要强调代码的集体所有制. 让开发人员轮换完成系统不同领域中的不同模块的不同任务. 另外一个好处, 就是可以降低由于人员流失造成的代码风险. 但有的场合下, 是不适用的. 比如一个高难度的实时控制系统, 这种代码需要某些特定的知识, 对特定的问题域有一定的了解, 这时候, 人多了反而会误事.
41. 成为指导者. 分享自己的知识.
42. 给别人解决问题的机会. 指给他们正确的方向, 而不是直接提供解决方案. 每个人都能从中学到不熟东西.
用问题回答问题, 可以引导提问的人走上正确的道路. 就算直接告诉他们答案, 也要解释为什么是这样.
43. 准备好以后再共享代码. 绝不要提交尚未完成的代码. 编译未通过或没有单元测试未通过的代码禁止提交.
在准备check in前对要提交的代码进行审查
结对编程. 不存在一个人独立进行编码的情况.
代码审查的checkList. 可以考虑使用的工具: Similarity Analyzer或jester.
1. 代码是否被读懂和理解
2. 代码是否有明显的错误
3. 代码是否会对系统其他部分产生不良影响
4. 是否存在复杂的代码
5. 是否存在可进行改进或重构的地方.
44. 复查所有代码。
代码复查需要积极评估代码的设计和清晰程度,而不只是考量变量名和代码格式是否符合组织标准。
要让所有复查人员得到每次复查活动的反馈,并让每个人知道复查完成后所采取的行动,同时必须及时跟进讨论出的建议
45. 及时通报进展和问题。发布进展状况,新的想法和目前正在关注的主题。不要等着别人来问项目进展如何。
1 指责不会修复BUG. 面对问题最先要考虑的是解决问题,而不是追究责任
2 不要追求快速的简单修复.要投入时间和精力去保持代码的整洁,敞亮
深入了解自己正在开发的那部分代码,从更高层面上了解系统中其他部分的代码,理解各个功能模块间是如何交互的
3 对事不对人,让我们骄傲的应该是解决了问题,而不是谁提出的方案
在开始寻求最好的解决方案之前,大家要对“最好”先达成一致,在开发者眼中最好的在用户看来可能不是,反之亦然
4 做正确的事,要诚实,有勇气的说出实情。但之前要确定自己看到了全部的实情,不然就不是勇敢而是鲁莽
5. 跟踪技术变化. 你不需要精通所有技术, 但需要清楚知道行业的动向, 从而规划你的项目和职业生涯.如果必须要把工作切换到一种新的技术领域, 可以不费大多时间做到
如果你是团队中最好的队员, 就没有动力继续提高自己. 如果周围的人都比你厉害, 你就会有很强的动力去追赶他们. 你将会在这种游戏中走向自己的顶峰.
6. 提供你和团队学习更好的平台. 午餐会议. 不是设计会议. 应该专注讨论一些与应用相关的一般性主题. 而具体的设计问题, 最好留在设计会议中去解决
优秀的管理者会重用那些能提高其他团队成员价值的人.
7. 拥抱变化. 掌握新方法的时候, 要舍弃就方法. 新技术会让人感到有点恐惧. 你确实需要学习很多东西. 已有的技能和习惯为你打下了很好的基础. 但不能依赖他们
过去电脑和CPU是昂贵的资源, 但现在开发者的时间才是紧缺和昂贵的资源.
学习新的语言, 新的技术, 不能把太多旧的态度,方法和思维用在新技术上. 但不是要完全摒弃旧的方法, 起码要保证, 不能习惯性的落入旧习惯旧思维. 否则, 你辛苦学习一门新的语言, 就失去了期望获得的益处
对于所使用的语言, 要总结熟悉的语言特性, 并且比较这些特性在新语言或者新版本中有什么不同
8. 不停的问为什么. 不能只满足于别人告诉你的表面现象. 要不停的提问知道你明白问题的根源
问为什么之前要想好你提问的理由, 这会有助于你提出恰当的问题
9. 保持迭代的时间间隔固定,但可以修改迭代的功能点。稳定多次的迭代会给人以鼓励和信心. 展示给用户可以使用的软件
10. 让真正使用软件的客户做决定,而不是开发者。不要让低级别和没有价值的问题影响客户,判断的标准是这个问题会不会影响到业务
11 让设计指导而不是操纵开发。好的设计是正确的,但不是精确的。不应该涉及到不确定的问题
12. 要合理的使用技术. 我们选择技术是为了解决问题, 而不是为了体验新框架. 所以首先要明确我们需要解决的问题, 在去评估技术方案. 任何技术方案都是有利弊的, 新技术就像是工具, 它可以使我们更好的工作, 它本身不应该成为工作内容
13 保持可发布. 通过分支, 规范代码提交等方法实现系统随时可编译发布, 并随时演示给用户. 这样才可以及时收到用户的反馈
14. 代码集成是很大的一块风险区, 所以应该提早集成, 频繁集成
15. 提早实现自动化部署, 让系统可以自动,方便,快速,完整的部署到用户的服务器上
16. 需求总是在变, 要保持应用可见, 每隔一段时间邀请所有用户, 频繁地给用户演示可以获取频繁的反馈, 就可以让软件更贴近用户的期望. 但要避免拿不能用或者缺少功能的版本演示, 这样只会让用户觉得愤怒
17. 增量开发. 发布带有最小却可用功能块的产品. 每个增量开发中, 使用1~4周左右迭代周期
18. 对于固定价格的应用开发,可以尝试的方法
1. 主动提议先构建系统最初的, 小的有用的部分. 挑选一系列小的功能,这样完成一次交付应该不大于6~8周. 但要能让用户真正使用
2. 一个迭代结束以后, 用户有两个选择. 一是选择一系列新功能,继续下一个迭代; 而是取消合同, 仅需支付第一个迭代几周的费用
3. 如果用户继续, 后面的迭代也是可供用户随时停止而不需要缴纳违约金. 他们甚至可以控制每个迭代的功能点, 这样从客户的角度来看, 他们可以更大程度的对项目进行掌控. 对他们而言, 降低了风险.
19. 使用自动化单元测试, 好的单元测试能够为你的代码问题提供及时的警报. 如果没有到位的单元测试, 不要进行任何设计和代码修改. 但单元测试要达到一定的测试覆盖率才会真正起作用
可以选择标准的测试框架, 如java的JUnit, webservice的HttpUnit等, 并让他们可以自动运行. 就像IDE的自动编译一样, 每次修改代码以后, 就会自动的进行单元测试, 来确保新修改的代码不会影响已有的功能. 这一步要做的事情, 就是在后台架设一个构建机器, 不断的获取最新版本的代码, 然后编译, 并进行单元测试, 有任何错误及时通知开发人员.
推荐书籍:<单元测试之道>,<项目自动化之道>
单元测试可以及时提供反馈, 符合敏捷开发中要持续获取反馈并完善优化的要求. 另外, 单元测试是有用的设计工具, 可信的文档以及学习的工具
20. 先用它再实现它. 也就是TDD(测试驱动开发), 会为你带来更简单有效的设计. 使你可以更加专注于设计接口, 而不会被太多实现的细节所干扰.
不要把测试优先和提交代码之前的测试等同起来.
21. 不同环境就有不同问题. 有了单元测试, 和自动持续集成构建的工具, 还需要在不同的环境中进行部署, 来警示不同操作系统不同环境下是否正常
22. 自动验收测试. FIT工具. 将对比正确结果与系统运算结果对比等这种需要人工的操作自动化.
23. 度量真实的进度. 不要使用不恰当的度量来欺骗自己或者团队, 或许这种很笼统的进度数据是用户需要的, 但它并不适用于开发团队内部. 要度量那些需要完成的待办事项.
24 编写清晰而不是讨巧的代码,代码的可读性要高于执行效率
25. 并不是注释多就是好的,注释多说明代码可读性差。好的代码应该是包含文档内容的,优雅而清晰简洁。代码自解释。
注释应该包含意图,期待结果,应该注意的地方。代码的逻辑及实现原理应该更多的从代码中获取。
26. 使用细心选择的有意义的命名,用注释描述代码意图和约束,注释不能代替优秀的代码。解释代码做了什么的注释用处并不大,注释要说明为什么这么写代码
27. 考虑性能,便利性,生产力,成本,上市时间。不要为了感觉上的性能提升和设计的优雅而将设计复杂化。过早的优化是万恶之源
28. 采用增量编程和测试,使用 测试优先的方式开发。关键在于持续做一些细小而有用的事情,而不是做一段长时间的编程和重构。这就是敏捷的方式
29. 开发可以工作的最简单的解决方案,除非有不可辩驳的原因,否则不要使用模式,原则和高难度技术之类的东西。但另一方面强行让代码变得优雅和过早的优化都会产生恶劣的影响
30. 高内聚。让类的功能尽可能的集中,让组件尽量小。要避免创建大的类和组件,不要创建无所不包的类
31. 告知不要询问。告诉他要做什么,然后继续自己的流程,而不是抢他的工作,由自己来决策。就是说,由自己来发消息而不是调用函数
面向过程的代码获取信息然后决策,面向对象的代码让别的代码去做事情。作为某段代码的调用者,开发人员不应该基于被调用对象的状态来做决策,更不能改变该对象的状态,这样的逻辑应该是被调用对象本身的,而不是你的责任。在对象之外替他做决策就会违反他的封装性
命令和查询分开,就是把功能和方法按照命令和查询分开存放。命令是指会产生内部影响的方法,查询没有副作用,尽提供给外部对象的状态而不会修改。
32. 通过替换代码来实现系统扩展。通过替换遵循接口契约的类,来添加并改进功能特性。多使用委托而不是继承。
继承和委托分别适用于什么情况下呢。
如果新类可以替换已有的类,并且他们之间的关系可以用is_a来描述,就使用继承。如果新类只是使用已有的类,并且两者之间的关系是has_a 或者uses_a ,就使用委托。这里的委托就是指聚合。
33. 维护一个问题及解决方案的日志。模板参考
问题发生时间;问题简述;解决方案详细描述;引用文章或网址提供更多信息和细节;任何代码片段,设置,对话框截屏等,有利于更加深入理解的细节
34. 将警告视为错误。
35. 隔离问题,将问题各个击破。识别复杂问题的第一步就是把他们分离出来,将问题域和周边分隔开
36. 处理或者向上抛出异常,不要自己捕获了但又不处理
37. 展示有用的错误信息,提供更易于查找错误的方式。发生问题时要展示出更多的支持细节,但不要让用户陷入其中。
建议的方法:将异常信息用链接方式隐藏;将异常信息由用户触发发送给系统后台;将系统异常日志做成rss feed;异常信息除了异常堆栈还应该包含当时的系统和用户快照;没有必要等待抛出异常才发现问题,可以使用断言;提供给用户的信息可以包含一个主键,以便定位日志位置
38. 使用立会可以使团队成员达成共识,但要保证会议短小精悍。
每个人只回答3个问题;在上班后的半个小时到一个小时之后。参与者只有开发者和团队直接管理者;立会时间不能超过30分钟。小团队可以两天或一周一次;要报告工作的细节
39. 优秀的设计从积极的程序员那里开始演化。积极的编程可以带来深入的理解。不要使用不愿意编程的架构师。
架构,设计,编码,测试彼此是不可分割的。如果架构师没有足够的时间来编码,可以让他不做正在进行的或工作量大的代码。不要允许任何人单独进行设计,特别是你自己
作为设计人员,只通过一些高度概括的粗略的设计图是无法了解系统的,更要深入到系统的具体细节中
40. 要强调代码的集体所有制. 让开发人员轮换完成系统不同领域中的不同模块的不同任务. 另外一个好处, 就是可以降低由于人员流失造成的代码风险. 但有的场合下, 是不适用的. 比如一个高难度的实时控制系统, 这种代码需要某些特定的知识, 对特定的问题域有一定的了解, 这时候, 人多了反而会误事.
41. 成为指导者. 分享自己的知识.
42. 给别人解决问题的机会. 指给他们正确的方向, 而不是直接提供解决方案. 每个人都能从中学到不熟东西.
用问题回答问题, 可以引导提问的人走上正确的道路. 就算直接告诉他们答案, 也要解释为什么是这样.
43. 准备好以后再共享代码. 绝不要提交尚未完成的代码. 编译未通过或没有单元测试未通过的代码禁止提交.
在准备check in前对要提交的代码进行审查
结对编程. 不存在一个人独立进行编码的情况.
代码审查的checkList. 可以考虑使用的工具: Similarity Analyzer或jester.
1. 代码是否被读懂和理解
2. 代码是否有明显的错误
3. 代码是否会对系统其他部分产生不良影响
4. 是否存在复杂的代码
5. 是否存在可进行改进或重构的地方.
44. 复查所有代码。
代码复查需要积极评估代码的设计和清晰程度,而不只是考量变量名和代码格式是否符合组织标准。
要让所有复查人员得到每次复查活动的反馈,并让每个人知道复查完成后所采取的行动,同时必须及时跟进讨论出的建议
45. 及时通报进展和问题。发布进展状况,新的想法和目前正在关注的主题。不要等着别人来问项目进展如何。