敏捷实践
一个大而笨重的过程会产生它本来企图去解决的问题.
每一位软件开发人员/每一个开发团队的职业目标,都是给他们的雇主和客户交付最大可能的价值.
敏捷联盟
敏捷联盟宣言包含如下四条:
- 个体和交互 胜过 过程和工具
- 可以工作的软件 胜过 面面俱到的文档
- 客户合作 胜过 合同谈判
- 响应变化 胜过 遵循计划
个体交互胜过过程和工具
合作/沟通以及交互能力要比单纯的编程能力更重要
使用过多的庞大/笨重的工具就像缺少工具一样,都是不好的.工具最好的状态,是够用就可以了.
团队的构建要比环境的构建重要的多.
可以工作的软件胜过面面俱到的文档
过多的文档比过少的文档更糟.
正确的文档应当是短小的(short一二十页)/主题突出的(salient仅论述系统高层结构和概括的设计原理)
给新的团队成员传授知识方面,最好的两份文档是代码和团队.
Martin文档第一定律
直到迫切需要并且意义重大时,才来编写文档.
客户合作胜过合同谈判
成功的项目需要有序/频繁的客户反馈.
大多数情况下,合同中指明的条款远在项目完成之前就变得没有意义.
响应变化胜过遵循计划
计划不能考虑的过远.
较好的做计划的策略是:为下两周做详细的计划,为下三个月做粗略的计划,在以后就做极为粗略的计划.
原则
- 我们最优先要做的是通过尽早的/持续的交付有价值的软件来使客户满意.
- 即使到了开发的后期,也欢迎改变需求.敏捷过程利用变化来为客户创造竞争优势.
- 经常性地交付可以工作的软件,交付的间隔可以从几周到几个月,交付的时间间隔越短越好.
- 整个项目开发期间,业务人员和开发人员必须天天在一起工作.
- 围绕被激励起来的个人来构建项目,给他们提供所需要的环境和支持,并且信任他们能够完成工作.
- 在团队内部,最具有效果并且富有效率的传递信息的方法,就是面对面的交谈.
- 工作的软件是首要的进度度量标准.
- 敏捷过程提倡可持续的开发速度.责任人,开发者和客户应该能够保持一个长期的/恒定的开发速度.
- 不断地关注优秀的技能和好的设计会增强敏捷能力.
- 简单–使未完成的工作最大化的艺术–是根本的(简单是根本的).
- 最好的构架/需求和设计出自于自组织的团队.
- 每隔一定时间,团队会在如何才能更有效的工作方面进行反省,然后相应的对自己的行为进行调整.
敏捷开发并不看重对于明天会出现的问题的预测,也不会在今天就对那些问题进行防卫.
极限编程概述
极限编程由一系列简单却相互依赖的实践组成.这些实践结合在一起形成一个胜于部分的结合整体.
1.客户作为团队成员.
客户指定义产品的特性并且排列这些特性优先级的人或者团队.
2.用户素材
了解需求只需要做到能够估算它的程度就足够了.
需求的特定细节很可能会随时间而改变.
3.短交付周期
迭代计划
- 通常耗时两周.
- 本次交付不一定会加到产品中.
- 迭代开始,用户就同意不再修改当次迭代中的用户素材的定义和优先级别
发布计划
- 规划随后大约6次迭代的内容的计划,通常需要三个月.
- 发布计划不是一成不变的,客户随时可以改变计划内容.
4.验收测试
一旦通过一项验收测试,就将该测试加入到集合中,并且决不允许该测试再失败.每次系统被创建,都要运行这个验收测试集.
5.结对编程
6.测试驱动开发
测试先于开发,测试用例与代码共同演化.快速迭代,通常几分钟左右.
7.集体所有权
没有程序员对任何一个特定的模块或技术单独负责.
8.持续集成
- 提交代码应该非常频繁.
- 提交前应当确保所有的测试都能通过.
9.可持续的开发速度
- 团队必须要有意识的保持稳定,适中的速度.
- 不允许团队加班.版本发布前一个星期例外.
10.开放的空间
充满积极讨论的屋子会提高生产效率.
11.计划游戏
每次发布和迭代计划之前,开发人员根据上一次迭代或者发布计划中所完成的工作量,给客户提供一个预算.客户选择成本合计少于预算的用户素材.
12.简单的设计
用最简单的方式实现第一批用户素材.
指导原则:
- 考虑能够工作的最简单的事情
- 你将不需要它(拒绝过度设计)
- 一次,并且只有一次(拒绝重复代码)
13.重构
重构就是在不改变代码行为的前提下,对其进行一系列小的改造,旨在改进系统结构的实践活动.
运行单元测试以确保重构没有造成任何破坏.
重构是我们每隔一个小时或者半个小时就要去做的事情.
14.隐喻
通过比喻让用户素材更形象的表达出来
计划
解释极限编程(XP)中的计划游戏.探索/发布计划/分解迭代计划/计划分解为任务/完成任务/完成计划,一系列流程像游戏中的发布/承接/完成任务.
初始探索
项目开始的时候,开发人员和客户确定所有真正重要的用户素材.不是全部用户素材,这是不可能的,随着项目的进展,用户会不断编写新的用户素材.
开发人员共同对这些素材进行估算.
引入”点数”的概念来分配,点数代表的时间并不确定,但是可以确定的是8个点数耗费的时间一定是4个点数的两倍.
适度分解素材,过大或过小的用户素材都难以估算.
引入”速度”的概念对应”点数”,比如”两天完成一个点数”.
随着项目的迭代,”速度”与”点数”的对应关系会越来越准确.一般的,从项目开始不明确速度到速度有一个较为明确的定位,大概会花费几天时间.
发布计划
速度明确后,客户对每个素材的成本有所了解.客户可以根据用户素材的优先级和开发代价(对应的点数)来选择想要最先完成的素材.
开发人员和客户对项目首次发布时间达成一致,2-4个月.客户挑选该发布中要实现的素材,并确定这些素材的实现顺序.
客户不能选择超出开发速度的更多素材.
开发速度会在迭代过程中进一步明确,根据明确的开发速度,进一步调整和完善发布计划.
迭代计划
开发人员和客户决定迭代规模,一般是两周.
客户决定要实现的功能,但是不能与当前开发速度不符.
迭代期间开发人员决定素材的开发顺序,采用最有技术意义的顺序.
迭代开始后,客户不能更改迭代内要实现的素材.但是可以随意更改迭代外的素材.
即使没有完成所有用户素材,迭代也要在先前指定的日期结束.
根据本次迭代所完成的素材点数,计算出本次迭代的速度.这个速度用作下一个迭代周期的速度.比如完成21个素材点,那么以后的开发速度就是每个迭代周期21个素材点.
任务计划
新的迭代开始时,开发人员和客户共同制定计划.
开发人员按照”一个开发人员4-16小时内可以实现的一些功能”来将素材分解成开发任务.开发人员在客户的帮助下,尽可能的列举出所有任务.
每个开发人员都知道在最近一次迭代完成的任务点数,这个数字是下一次迭代的个人预算.不能领取超个人预算的任务点数.
根据任务的分配情况,与客户要求删除或者增加素材.
迭代进行一半的时候,进行会议.这个时间点应该有半数的素材完成.如果没有达成这个目标,考虑重新分配没有完成的任务和职责,以保证迭代按期望完成.如果分配好还是悲观,与客户协商删减素材或者排列素材优先级.
迭代中点期望的结果是有一半素材点数的完整的素材被完成.
迭代
每次迭代结束,给客户演示当前可运行的项目.
测试
单元测试是一种验证行为/设计行为/文档行为.单元测试可以避免相当数量的反馈循环.
测试套件运行起来越简单,就会越频繁的运行他们.测试运行的越多,就会越快地发现和测试的任何背离.
测试驱动开发的方法
在设计和编写产品代码之前,先编写好相应的测试代码.
影响:
- 为以后的开发提供支援.完善的测试套件可以告诉我们做出某些修改之后程序是否还在成功的运行,这样我们就可以更自由的改进程序.
- 迫使程序员使用不同的观察点.
- 迫使自己把程序设计成可测试的.
- 测试是一种文档形式.
测试促使模块之间的隔离.在编写产品代码之前,先编写测试常常会暴露程序中被耦合的区域.为了测试而对模块之间进行隔离的需要,迫使我们以对整个程序都有益的方式对程序进行解耦合.
验收测试
单元测试是用来验证系统中个别机制的白盒测试.
验收测试是用来验证系统满足客户需求的黑盒测试.
验收测试由不了解系统内部机制的人编写.
验收测试是有关系统特性的可编译/执行的文档.
验收测试会迫使程序员从很高的系统架构层面对系统进行解耦合.当前的很多成熟的系统架构,已经做出了很成熟的分层解耦实践,比如经典的mvc/后端三层架构等,引入这些架构而非自己去从无到有造轮子.站在前人的肩膀上.
自动化验收测试应该从项目初期就必须设计实现,以保证项目得到自动化测试带给系统进行解耦合的促进力.
创建一个验收测试框架是一件很困难的事情,不同迭代内只需要完成对单个迭代包含的特性进行验收测试所需要的那部分.
重构
软件模块的三个职责:
- 完成功能.这是该模块得以存在的原因.
- 应对变化
- 与阅读他的人进行沟通
重构的目的在于,在完成功能的大前提下,让软件模块更易于阅读,易于修改.
提取出函数所增加的可读性是值得花费额外的一些微小开销的.先假设这些微小开销并不会影响系统运行,如果真的出现影响的情况,再去解决.
重构就好比用餐后对厨房的清理工作.每天清理你的代码,不要让脏乱积累.
在<重构>里提到过,重构应该是对程序员来说应该是一件频繁的事情,对程序员来说就像空气一样,出现在编码的所有地方.