1. 前言
1. 敏捷开发(Agile Development)是一种面临迅速变化的需求快速开发软件的能力。
2. 第一章 敏捷实践 P2
1. 不断增加更多的约束和人为制品导致一个大而笨重的过程的产生。
大而笨重的过程就是庞大、重型的过程方法。
2. 敏捷软件开发宣言:
1. 个体和交互 胜过 过程和工具
2. 可以工作的软件 胜过 面面俱到的文档
3. 客户合作 胜过 合同谈判
4. 响应变化 胜过 遵循计划
3. 个体和交互胜过过程和工具
1. 人是获得成功的最为重要的因素。
不好的过程会使最优秀的团队成员失去效用。
2. 合作、沟通以及交互能力要比单纯的编程能力更为重要。
所以一个优秀的团队成员可能是一个平均水平的程序员,但是却能够很好地和他人合作。
3. 合适的工具对于成功来说非常重要。
但使用过多庞大、笨重的工具就像缺少工具一样,都是不好的。
4. 团队的构建要比环境的构建重要得多。
首先应该致力于构建团队,然后在让团队基于需要来构建环境。
4. 可以工作的软件胜过面面俱到的文档
1. 团队需要编制易于阅读的文档,来对系统及其设计决策的依据进行描述。
2. 过多的文档比过少的文档更糟。
文档和代码同步的恶梦。
3. 文档应该短小并且主题突出。
短小是指最多一二十页。
主题突出是指尽论述系统的高层结构和概括的设计原理。
4. Martin文档第一定律:
直到迫切需要并且意义重大时,才来编写文档。
5. 客户合作胜过合同谈判
1. 成功的项目需要有序、频繁的客户反馈。
不是依赖合同或者关于工作的陈述,而是让软件的客户和开发团队密切地在一起工作,并尽量经常地提供反馈。
2. 坏合同
一个指明了需求、进度以及项目成本的合同存在根本上的缺陷。
3. 好合同
那些为开发团队和客户的协同工作方式提供指导的合同才是最好的合同。
4. 合同中不应该详细指明功能模块和验收细节。
6. 响应变化胜过遵循计划
1. 构建计划时,应该确保计划是灵活的并且易于适应商务和技术方面的变化。
2. 较好的做计划的策略是:
为下两周做详细计划,为下三个月做粗略计划,再以后就做极为粗糙的计划。
3. 仅仅对于迫切的任务才花费时间进行详细计划。这样计划的其余部分仍然保持着灵活性。
7. 敏捷宣言遵循的12条原则:
1. 我们最优先要做的是通过尽早的、持续(经常)的交付有价值的软件来使客户满意。
1. 两个相关性
尽早地交付具有部分功能的系统和系统质量之间具有很强的相关性。
初期交付的系统中所包含的功能越少,最终交付的系统的质量就越高。
以逐渐增加功能的方式经常性地交付系统和系统质量之间具有很强的相关性。
交付得越频繁,最终交付的系统的质量就越高。
2. 即使到了开发的后期,也欢迎改变需求。敏捷过程利用变化来为客户创造竞争优势。
1. 需求改变意味着团队已经学到了很多如何满足市场需要的知识。
3. 经常性地交付可以工作的软件,交付的间隔可以从几周到几个月,交付的时间间隔越短越好。
1. 关注的目标是交付满足客户需要的软件,而不是大量的文档或计划。
4. 在整个项目开发期间,业务人员和开发人员必须天天都在一起工作。
1. 通过客户、开发人员以及涉众之间有意义的、频繁的交互,对软件项目进行持续不断地引导。
5. 围绕被激励起来的个人来构建项目。给他们提供所需要的环境和支持,并且信任他们能够完成工作。
1. 人是项目取得成功的主要因素。
过程、环境、管理等都是次要因素。
当次要因素对人有负面影响时,就要对次要因素进行改变。
6. 在团队内部,最具有效果并且富有效率的传递信息的方式,就是面对面的交谈。
1. 交谈是默认的沟通方式。
7. 工作的软件是首要的进度度量标准。
1. 不是根据所处的开发阶段、已经编写的文档的多少或者已经创建的基础结构(infrastructure)代码的数量来度量开发进度。
8. 敏捷过程提倡可持续的开发速度。责任人、开发者和用户应该能够保持一个长期的、恒定的开发速度。
1. 敏捷项目不是50米短跑,而是马拉松长跑。
2. 以快速但是可持续的速度行进。
9. 不断地关注优秀的技能和好的设计会增强敏捷能力。
1. 高的产品质量是获取高的开发速度的关键。
2. 高质量就是尽可能的简洁、健壮。
10. 简单--使未完成的工作最大化的艺术--是根本的。
1. 采用和目标一致的最简单的方法。
2. 并不看重对于明天会出现的问题的预测,也不会在今天就对那些问题进行防卫。
3. 深信如果在明天发生了问题,也会很容易进行处理。
11. 最好的构架、需求和设计出自于自组织的团队。
1. 敏捷团队的成员共同来解决项目中所有方面的问题。
12. 每隔一定时间,团队会在如何才能更有效地工作方面进行反省,然后相应地对自己的行为进行调整。
1. 反省的方面包括:
团队的组织方式、规则、关系等。
8. 敏捷过程有:
1. SCRUM
2. Crystal
3. 特征驱动软件开发(Feature Driven Development)(FDD)
4. 自适应软件开发(Adaptive Software Development)(ADP)
5. 极限编程(eXtreme Programming)(XP)
3. 第二章 极限编程概述 P9
1. 极限编程(eXtreme Programming,简称XP)
极限编程是一组简单、具体的实践,这些实践结合在一起形成了一个敏捷开发过程。
2. 客户作为团队成员
XP团队中的客户是指定义产品的特性并排列这些特性优先级的人或团体。
如果确定无法和客户在一起工作时,那么应该去寻找能够在一起工作、愿意并能够代替真正客户的人。
3. 用户素材(user stories)
1. 用户素材就是正在进行的关于需求谈话的助记符。
2. 用户素材是一个计划工具,客户可以使用它并根据它的优先级和估算代价来安排实现该需求的时间。
3. 在离真正实现需求还很早时就去捕获该需求的特定细节,很可能会导致做无用功以及对需求不成熟的关注。
4. 短交付周期
1. XP项目每两周交付一次可以工作的软件。
2. 每两周的迭代(iteration,也可称为重复周期或循环周期)都实现了涉众的一些需求。
3. 迭代计划
1. 迭代计划是由客户根据开发人员确定的预算而选择的一些用户素材。
2. 开发人员通过度量在以前的迭代中所完成的工作量来为本次迭代设定预算。
3. 一旦迭代开始,客户就不再修改当次迭代中用户素材的定义和优先级别。
4. 发布计划
1. 一个发布计划规划大约6次迭代的内容。
2. 一次发布通常需要三个月的时间。
3. 同设定迭代预算一样
开发人员通过度量在以前的发布中所完成的工作量来为本次发布设定预算。
4. 不用在初期就把全部6次迭代的内容都制定好,只需制定出发布中最初几次迭代的内容即可。
5. 灵活性
发布计划不是一成不变的,客户可以随时改变计划的内容。
5. 验收测试
1. 可以以用户指定的验收测试(Acceptance Tests)的形式来捕获有关用户素材的细节。
2. 用户素材的验收测试是在就要实现该用户素材之前或实现用户素材的同时编写的。
3. 验收测试使用能够让它们自动并反复运行的某种脚本语言编写
,这些测试共同验证系统按照用户指定的行为运转。
6. 结对编程
1. 所有的产品代码都是由结对的程序员使用同一台电脑共同完成的。
2. 结对的关系每天至少改变一次,以便于每个程序员在一天中可以在两个不同的结对中工作。
3. 在一次迭代期间,每个团队成员应该和所有其他的团队成员在一起工作过,并且他们应该参与了本次迭代中所涉及的每项工作。
4. 结对编程的好处:极大的促进了专业知识在团队中的传播。
7. 测试驱动的开发方法:
1. 编写所有产品代码的目的都是为了使失败的单元测试能够通过。
2. 首先编写一个单元测试,由于它要测试的功能还不存在,所以单元测试会运行失败。然后编写产品代码使单元测试通过。
3. 最后可以得到一个非常完整的测试用例集。
4. 测试驱动的一个好处:解除各个模块间的耦合。
8. 集体所有权
没有程序员对任何一个特定的模块或技术单独负责。
9. 持续集成
1. XP团队使用非阻塞的(nonblocking)源代码版本控制工具。
2. 检入(check in)要确保所有的测试(单元测试和验收测试)都能够通过。
10. 可持续的开发速度
1. 软件项目不是全速的短跑,它是马拉松长跑。
2. 团队必须要有意识的保持稳定、适中的速度。
11. 开放的工作空间
充满积极讨论的屋子(war room)里工作,生产率非但不会降低,反而会成倍地提高。
12. 计划游戏(planning game)
1. 计划游戏的本质是划分业务人员和开发人员的职责。
业务人员(即客户)的职责是决定产品特性的重要性。
开发人员决定实现一个产品特性所花费的时间。
2. 客户选择用户素材的规则:
在每次发布和每次迭代的开始,开发人员基于在最近一次迭代或者最近一次发布中他们所完成的工作量,为客户提供一个预算。
客户选择那些所需的成本合计起来不超过该预算的用户素材。
13. 简单的设计
1. XP团队使他们的设计尽可能地简单、具有表现力(expressive)
2. XP团队仅仅关注于计划在本次迭代中要完成的用户素材,不会考虑那些未来的用户素材。
3. 三条XP指导原则(mantras)
1. 考虑能够工作的最简单的事情。
XP团队总是尽可能寻找能实现当前用户素材的最简单的设计。
2. 你将不需要它。
引入基础结构(如:数据库、ORB等)的时机:
只有在有证据,或者至少有十分明显的迹象表明现在引入这些基础结构比继续等待更加合算时,XP团队才会引入这些基础结构。
3. 一次,并且只有一次。
极限编程者不能容忍重复的代码。
无论在哪里发现重复的代码,都要消除他们。
消除重复最好的方法就是抽象。抽象又能进一步减少代码间的耦合,这是个良性循环。
14. 重构
1. 定义:
重构就是在不改变代码行为的前提下,对其进行一系列小的改造,旨在改进系统结构的实践活动。
2. 作用:
代码往往会腐化,重构的作用就是扭转这种腐化。
3. 重构是持续进行的,是每隔一个小时或者半个小时就要去做的事情。
15. 隐喻
1. 隐喻就是对整个系统做个比喻
2. 隐喻是将整个系统联系在一起的全局视图,是系统的未来景象。
隐喻使得所有单独模块的位置和外观变得明显直观。
如果模块的外观与整个系统的隐喻不符,那么就知道该模块是错误的。
3. 隐喻通常可以归结为一个名字系统。
这些名字提供了一个系统组成元素的词汇表,并且有助于定义它们之间的关系。
4. 把一个分析网络流量的系统隐喻成烤面包机。
数据块被称为“面包切片”
分析程序被称为“烤制面包切片”
整个系统被称为“烤面包机”
数据块中的单个变量被称为“面包屑”
4. 第三章 计划 P17
1. 初始探索
1. 在项目开始时,开发人员和客户会尽量确定出所有所有真正重要的用户素材,但并不会确定所有的用户素材。
随着项目进展,客户会不断编写新的用户素材。
素材的编写会一直持续到项目完成。
2. 探究、分解和速度
1. 任何过大的用户素材都应该分解成小一点的部分。
任何国小的用户素材都应该和其它小的素材合并。
2. 当分割或合并一个用户素材后,应该对其重新进行估算。
简单地加上或者减去估算值都是不明智的。
3. 对一个用户素材进行分解或者合并的主要原因
为了使其大小适于被准确地估算。
4. 速度(velocity)因子
将用户素材的估算点数乘以速度得到实现该用户素材的实际开发时间。
5. 计算团队的开发速度
花费几天时间去原型化一到两个用户素材来了解团队的速度。
这样的一个原型化的过程称为探究
2. 发布计划
当开发速度变得更准确一点时,可以再对发布计划进行调整。
选择发布计划中完成的用户素材,属于商务决策范畴。
3. 迭代计划
1. 迭代期间用户素材的实现顺序属于技术决策范畴。
2. 一旦迭代开始,客户就不能再改变该迭代期内需要实现的用户素材。
3. 即使没有完成所有的用户素材,迭代也要在预先指定的日期结束。
4. 迭代完成后的工作:
合计所有已完成的用户素材的估算值,然后计算出本次迭代的开发速度。
5. 为每次迭代做计划时采用的开发速度,就是前一次迭代中测算出来的开发速度。
4. 任务计划
1. 在新的迭代开始时,开发人员和客户共同制定计划。
具体方法:
开发人员把用户素材分解成开发任务,一个任务就是一个开发人员能够在4~16小时(半天~两天)之内实现的功能。
开发人员在客户的帮助下对这些用户素材进行分析,并尽可能完全地列举出所有的任务。
2. 迭代中点
1. 在迭代进行到一般的时候,本次迭代中所安排的半数用户素材应该被完成。
如果没有完成,那么团队应该设法重新分配没有完成的任务和职责,以保证在迭代结束时能够完成所有的用户素材。
2. 目标是要完成用户素材,而不仅仅是任务。
3. 在迭代的中点,希望看到拥有一半素材点数的完整的用户素材被完成。
5. 迭代
每次迭代结束后的工作:
1. 给客户演示当前可运行的程序。
2. 要求客户对项目程序的外观、感觉和性能进行评价。
3. 客户会以新的用户素材的方式提供反馈。
5. 第四章 测试 P21
1. 编写单元测试是一种验证行为,也是一种设计行为,更是一种编写文档的行为。
2. 编写产品代码就是为了通过测试。
3. 测试驱动的开发方法产生的效果:
1. 程序中的每一项功能都有对应的测试来验证他的操作的正确性。
2. 可以使开发人员使用不同的观察点。
从程序调用者的有利视角去观察将要编写的程序。
这样就会在关注程序的功能的同时,直接关注程序的接口。
就可以设计出便于调用的软件。
3. 迫使开发人员把程序设计为可测试的。
为了成为易于调用和可测试的,程序必须和它的周边环境解耦。
在编写产品代码之前,先编写测试代码常常会暴露程序中应该被解耦合的区域。
产品程序越是具有可测试性,耦合关系就越弱。
4. 测试可以作为一种无价的文档。
测试就像一套范例,它帮助其他程序员了解如何使用代码。
单元测试是可编译、可运行的有关系统内部结构的文档。它始终保持最新,不会和产品程序不同步。
程序员能轻松阅读单元测试。
4. 有意图的编程(intentional programming)
相信只要按照测试所暗示的结构去编写产品程序,就能够通过测试。
5. MOCK OBJECT(仿制的对象)模式
在被测试的类以及它的所有协作者之间插入接口,创建实现这些接口的测试桩(test stub)
6. 单元测试的功能:
单元测试用来验证系统的小的组成单元应该按照所期望的方式工作。
单元测试是用来验证系统中个别机制的白盒测试(white-box tests)。
单元测试没有验证系统作为一个整体时工作的正确性。
7. 验收测试的功能:
验收测试是用来验证系统满足客户需求的黑盒测试(black-box tests)。
验收测试是可编译、可运行的有关系统特性的文档。
客户能轻松阅读验收测试。
为了使系统具有可测试性,就必须要在很高的系统构架层面对系统进行解耦合。
8. 编写验收测试
通常使用专为应用程序的客户创建的脚本语言来编写验收测试。
验收测试应该便于编写并且易于改变,所以采用简单的文本文件来编写。
CSV文件是编写验收测试的不错选择。
9. 验收测试是关于一项特性的最终文档。
6. 第五章 重构 P28
1. 重构的目的是使每一个软件模块都具有下列三项职责。
1. 第一个职责是每一个软件模块运行起来所完成的功能。
2. 第二个职责是每一个软件模块要应对变化。
3. 第三个职责是每一个软件模块要和阅读它的人进行沟通。
2. 原则和模式可以帮助开发人员创建更加灵活和具有适应性的软件模块。
但是要使软件模块易于阅读和修改,就不仅需要原则和模式,还需要纪律约束和开发人员创造美的激情。
3. 一个素数产生程序的例子,演示简单的重构 P29
4. IntelliJ Idea 一个JAVA IDE,内置重构浏览器
官方网站
http://www.jetbrains.com/idea/
IntelliJ IDEA v4.5.1 注册码
Name:crsky
Code:12919-DD8VQ-UVPQ0-10TMG-F5VNN-B2OA7
5. 一般方法名是一个动词短语,类名是一个名词短语。
6. 多个细小的重构之后,要再全部读一遍产品代码。
因为重构的都是代码片断,最后再读一遍可以看看把这些片断结合在一起是否是一个具有可读性的整体。
7. 重构和单元测试密不可分。
每次小碎步的重构之后,都要确保产品代码能正确通过单元测试。
8. 为重构投入的时间和随后为自己和他人节省的努力相比起来是非常少的。
9. 一个很贴切的把重构比喻成清洁工作的例子 P38
用重构来保持代码的清洁。
7. 第六章 一次编程实践 P39
1. 一个开发保龄球比赛计分程序的敏捷实践过程。
2. 从简单考虑,加入类Frame并非必要,只要加入一个整数数组就能实现期望的功能。
3. 让程序遵循原则的事情,可以稍后交给重构做。
而不需要在最初的设计阶段就很小心的让程序遵循原则。
4. 先使程序更易读。
再继续向程序中添加更多功能。
5. 不仅产品代码需要重构,测试代码也需要重构。
6. 如果代码使用了局部变量,就不能被提取函数,除非把这些局部变量变为成员变量。
7. 通过重构,尽量使产品代码的结构更像易读的伪代码。
8. 何时不需要图示
在创建了它们而没有验证它们的代码就打算去遵循它们时,图示就是无益的。
画一副图来探究一个想法是没错的。但是,画一副图后,不应该假定该图就是相关任务的最好设计。
最好的设计是首先编写测试,然后一小步一小步前进时逐渐形成的。