敏捷开发修炼之道阅读笔记2
4. 支付用户想要的软件
没有任何计划在遇敌后还能继续执行。
- 让客户做决定
- 在设计方面,做决定的时候必须有开发者参与。
- 决定什么不该决定
判断哪些是自己决定不了的,应该让企业主决定 - 让你的客户做决定
开发者、经理或者业务分析师不应该做业务方面的决定。用业务负责人能够理解的语言,向他们详细解释遇到的问题,并让他们做决定。 - 记录客户做出的决定,并注明原因。
- 不要用过于具体和没有价值的原因打扰繁忙的业务人员。如果问题没有影响,就应该是没有价值的。
- 让设计指导而不是操作开发
- 设计满足实现即可,不必过于详细
- 设计可以分为两层:
- 战略
只描述总体战略,不应深入到具体的细节,扮演的是地图的角色,指引你向正确的方向前进。 - 战术
战术设计的重点是集中在单个的方法或数据类型上。这时适合讨论如何设计类的职责。
- 战略
- 好设计是一张地图,它也会进化。
设计指引你向正确的方向前进,它不是殖民地,他不应该标识具体的路线。你不要被设计操纵。
-
合理地使用技术
- 盲目地为项目选择技术框架,就好比是为了少交税而生孩子。
- 找到了需要解决的问题,接下来需要考虑:
- 这个技术框架真的能解决这个问题吗?
如果需要,先做一个小的原型。 - 你将会被它拴住吗?
一些技术缺乏可取消性,一旦你使用了它,就会被它套牢,再也不可能回头了。 - 维护成本是多少?
- 这个技术框架真的能解决这个问题吗?
- 不要开发你容易下载到的东西
- 根据需要选择技术
首先决定什么是你需要的,接着为这些具体的问题评估使用技术。对任何要使用的技术,多问一些挑剔的问题,并真实地作出回答。
-
保持可以发布
- 已提交的代码应该随时可以行动
- 防止你提交破坏系统代码的简单工作流程:
- 在本地运行测试
- 检出最新的代码
- 提交代码
- 持续集成系统
在后台不停地检出、构建和测试代码的应用 - 保持你的项目时刻可以发布
保证你的系统随时可以编译、运行、测试并立即部署
-
提早集成,频繁集成
- 集成和独立不是相互矛盾的,你可以一边进行集成,一边进行独立开发。
- 决不要做大爆炸式的集成
- 代码集成是主要的风险来源。要想规避这个风险,只有提早集成,持续而有规律地进行集成
-
提早实现自动化部署
- 质量保证人员(QA)应该测试部署过程
- 一开始就实现自动化部署应用
使用部署系统安装你的应用,在不同的机器上用不同的配置文件测试依赖的问题。质量保证人员要像测试应用一样测试部署。
-
使用演示获得频繁反馈
- 需求就像是流动着的油墨
- 清晰可见的开发
在开发的时候,要保持应用可见(而且客户心中也要了解)。每隔一周或者两周,邀请所有的客户,给他们演示最新完成的功能,积极获得他们的反馈。
-
使用短迭代,增量发布
- 统一过程和敏捷方法都使用迭代和增量开发。
- 迭代开发: 你在小且重复的周期里完成各种开发任务:分析、设计、实现、测试和获得反馈。
- 给我一个详细的长期计划,我就会给你一个注定完蛋的项目
- 增量开发: 发布带有最小却可用功能块的产品。每个增量开发中,使用1~4周左右迭代周期。
-
固定的价格就意味着背叛承诺
- 基于真实工作的评估
让团队和客户一起,真正地在当前项目中工作,做具体实际的评估。由客户控制他们想要的功能和预算。
- 基于真实工作的评估
5. 敏捷反馈
-
守护天使
- 编写能产生反馈的代码
- 自动化单元测试
- 确保测试是可重复的
- 测试你的边界条件
- 不要放过任何一个失败的测试
- 单元测试能及时提供反馈
- 单元测试让你的代码更加健壮
- 单元测试是有用的设计工具
- 单元测试是让你自信的后台
- 单元测试是解决问题时的探测器
- 单元测试是可信的文档
- 单元测试是学习工具
- 使用自动化的单元测试
好的单元测试能够为你的代码问题提供及时的警报。如果没有到位的单元测试,不要进行任何设计和代码修改。
-
先用他再实现它
- 编码之前,先写测试
- 好的设计并不意味着需要更多的类。
- 将TDD(Test Driven Development)作为设计工具,它会为你带来更简单更有效用的设计。
-
不同环境,就有不同问题
- 使用自动化会节省时间
- 使用持续集成工具,在每一种支持的平台和环境中运行单元测试。要积极地寻求问题,而不是等问题来找你。
-
自动验收测试
- 为核心的业务逻辑创建测试
让你的客户单独验证这些测试,要让它们像一般的测试一样可以自动运行。
- 为核心的业务逻辑创建测试
-
度量真实的进度
- 专注于你的方向
- 不要用不恰当的度量来欺骗自己或者团队。要评估那些需要完成的待办事项。
-
倾听用户的声音
- 这是一个bug
- 每一个抱怨的背后都隐藏了一个事实
找出真相,修复真正的问题
6. 敏捷编码
-
代码要清楚的表达意图
- 设计软件有两种方式。
一种是设计得尽量简单,并且明显没有缺陷。另外一种方式是设计的尽量复杂,并且没有明显的缺陷。 - PIE(Program Intently and Expressively)原则
代码必须明确说明你的意图,而且必须富有表达力。这样可以让代码更易于被别人阅读和理解。代码不让人感到迷惑,也就减少了发生潜在错误的可能。一言以蔽之,代码应意图清晰,表达明确。 - 要编写清晰的而不是讨巧的代码
向代码阅读者明确表明你的意图。可读性差的代码一点都不聪明。
- 设计软件有两种方式。
-
用代码沟通
- 不要用注释来包裹你的代码
- 注释可用来为读者指定一条正确的代码访问路线图。为代码中的每个类或模块添加一个短小的描述,说明其目的以及是否有特别的需求。对于类中的每个方法可能要说明以下信息:
- 目的: 为什么需要这个方法
- 需求(前置条件): 方法需要什么样的输入,对象必须处于何种状态,才能让这个方法工作
- 承诺(后置条件) :方法成功执行后,对象处于什么样的状态,有那些返回值。
- 异常:可能会发生什么样的问题, 会抛出什么样的异常。
- 用注释沟通
使用细心选择的、有意义的命名。用注释描述代码意图和约束。注释不能代替优秀代码。
-
动态评估取舍
- 没有最佳解决方案
- 动态评估权衡
考虑性能、便利性、生产力、成本和上市时间。如果性能表现足够了,就将注意力方法其他因素上。不要为了感觉上的性能提升或者设计上的优雅,而将设计复杂化。
-
增量式编程
- 关键在于持续做一些细小而有用的事情,而不是做一段长时间的编程或重构。
- 在很短的编辑/构建/测试循环中编写代码
这要比花费长时间仅仅做编写代码的工作好得多。可以创建更加清晰、简单、易于维护的代码。
-
保持简单
- 简单不是简陋
- 开发可以工作的、最简单的解决方案
除非·有不可辩驳的原因,否则不要使用模式、原则和高难度技术之类的东西。
-
编写内聚的代码
- 内聚性用来评估一个组件(包、模块或配件)中成员的功能相关性。
- 让类的功能尽量集中,让组件尽量小。
要避免创建很大的类或组件,也不要创建无所不包的大杂烩类。
-
告知, 不要询问
- 面向过程的代码取得信息,然后做出决策。面向对象的代码让别的对象去做事情。
- 将命令与查询分离开来
- 不要抢别的对象或是组件的工作。告诉它做什么,然后盯着你自己的职责就好了。
-
根据契约进行替换
- Liskov替换原则:任何继承后得到的派生类对象,必须可以替换任何被使用的基类对象,而且使用者不必知道任何差异。
- 针对is-a关系使用继承;针对has-a或uses-a关系使用委托
- 通过替换代码来扩展系统:通过替换遵循接口契约的类,来添加并改进功能特性。要多使用委托而不是继承。

浙公网安备 33010602011771号