功能驱动开发模式FDD
FDD(Feature-Driven Development)是由Peter Coad、Jeff de Luca 、Eric Lefebvre共同开发的一套针对中小型软件开发项目的开发模式。
FDD是一个模型驱动的快速迭代开发过程,它强调的是简化、实用、 易于被开发团队接受,适用于需求经常变动的项目。简单地说,FDD“是一个以Architecture为中心的,采用短迭代期,目期驱动的开发过程。它首先对整个项目建立起一个整体的模型,然后通过两周一次‘设计功能-实现功能’的迭代完成项目开发”。此处的“功能”是指“用户眼中最小的有用的功能”,它是可理解的、可度量的,并且可以在有限的时间内(两周)实现。在开发过程中,开发计划的制定、报告的生成、开发进度的跟踪均是以上述“功能”为单位进行的。在FDD中,它认为:只有良好定义的并且简单的过程才能被很好地执行。另外,由于在FDD中采用了短周期的迭代,最小化的功能划分法,所以可以对项目的开发进程进行精确及时地监控。
FDD的使用需要有相应工具的支持,Peter Coad等人开发出了一套扩展的UML(FDD UML Extensions),并在Together中实现有关的功能,详细内容可参见后文。
在FDD中,存在“主要功能集”、“功能集”、“功能”等概念,它们之间的关系及示例如下所示:
主要功能集 = 功能集1 + 功能集2 + …
功能集 = 功能1 + 功能2 + …
其中,主要功能集是在初始阶段根据用户的需求所制定出来的比较粗的,有待于细化的对开发项目所需要功能的描述;功能是在开发过程细化的结果,在每个迭代期中需要实现若一干个功能,这些功能的集合被称之为功能集。
在FDD中,它将开发过程划分为如下五个阶段:
l 制定整体的模型
l 根据优先级列出功能的详细列表
l 依据功能制定计划
l 依据功能进行设计
l 实现功能
每个阶段的定义又是通过被称之为:ETVX的方法从下面四个方面加以描述的:
l Entry:Specify clear and well defined entry criteria for the process;
l Task:列出所有要实现的任务列表,名称,是否需要实现,任务描述;
l Verification:;制定对过程结果的评批标准;
l eXit:过程结束时所需的结果;
FDD过程示意图
在FDD中主要存在三类人员:主要开发人员、类的所有者、功能团队,它们各自的含义如下:
l 主要开发人员:用于领导其它开发人员进行DBF/BBF的开发,对开发工作进行监督(例如对设计及代码进行审查)。主要开发人员的数量由项目整体的大小所决定,如果需要加快开发进度则可以再培养新的主要开发人员。与其它开发人员相比,主要开发人员具有更高的开发效率。Fred Brooks在几十年前就提出了:增加开发人员数量只会降低开发效率。但对于小型的,以用户功能驱动的轻量及的开发过程此原则并不适用。在此过程中采用增加人员的方法可以提高开发的并行效率。
l 类的所有者:一个类有且只有一个所有者,即一个类只能由一名开发人员进行设计及编码。采用这种方式是十分有效的,因为开发人员会感觉他拥有了部分属于自已的代码,他会以此为荣;此外,它还可以保证相关代码的一致性。如果此类中包含有复杂的算法,那么可以再增加一名专门负责算法的开发人员。虽然FDD是面向用户功能的,而不是面向类的,但用户最终关心的是那些他们需的功能,而并不关心在开发时采用何种框架模式,所以在此以类为单位进行人员分配与开发的宗旨并不矛盾。
l 功能团队:开发时功能会被分配给主要开发人员,再由主要开发人员根据实现此功能所需类的所有关系找到有关的开发人员从而构成一个临时的(最多两周)的团队。一名开发人员可以同时负责多个类的开发工作,即他可以在同一时刻处于多个功能团队中。因此在每个DBF/BBF中功能团队的人员均可能发生变化。在此团队中主要开发人员处于核心地位,团队内部的交流也是经及为中心的。采用这种方法可以加速开发进度,并且主要开发人员还可以对过程进行必要的监控,保证设计与实现的一致性。从更高的角度来看,主要的系统设计师又负责监控各功能团队中的主要开发人员。
采用FDD方式进行开发时,各阶段时间的分配关系大致如下所示:
l Develop an overall model 10% initial, 4% on-going
l Build a features list 4% initial, 1% on-going
l Plan by feature 2% initial, 2% on-going
l Design by feature, build by feature 77%(两周一个迭代期)
DBF/BBF中各阶段时间分配关系:
l DBF
² Walk through the domain 1%
² Design 40%
² Inspect the design 3%
l BBF
² Code/test 45%
² Inspect the code 10%
² Promote to build 1%
需要注意的是:上述Coding的过程中还包含有单元测试的内容。此外单从DBF/BBF的过程来看,设计所有的时间要比编码的时间长(40% : 45%),但考虑到FDD的整个实施过程(包括前期的建模过程),设计的时间还是比编码的时间要长的(45% : 35%)。
在FDD中另一个重要的,并且也是十分有特色的部分就是它的报告功能。每周Release经理要召开一次会议,会议一般限定于30分钟以内,在会上每个主要的开发人员全面地介绍其所做的工作,并标识出相应的项目状态图。通过这种口头上的交流,可以确保各主要开发人员能对项目的其它部分有一个充分的了解。会后,Release经理还要根据有关内容更新数据库中的信息并生成相应的报告,这个报告将发送给项目团队、用户以及主要的管理人员。
为跟踪项目开发状态需要使用数据库对有关内容加以保存,在数据库中应保存如下信息:
l 类型(问题域、人的交互活动、系统交互活动)
l 标识(功能集前缀+序列号)
l 状态(正在处理、不再需要、正常)
l 主要功能集
l 功能集
l 文档引用信息
l 活动事件
l 主要开发人员
l 问题域分析时的计划日期,实际日期
l 设计时的计划日期,实际日期
l 设计复查时的计划日期,实际日期
l 编码时的计划日期,实际日期
l 编码复查时的计划日期,实际日期
l 提交构造时的计划日期,实际日期
l 备注
项目计划表
功能详细列表
另外,有关类及类的所有者的信息保存在其它的表中。根据数据库可自动生成有关报告。
项目已完成功能统计表
FDD中扩展的UML
Entry Criteria:
客户已准备好建立一个系统。他已经有采用某种形式保存的需求列表。此时用户可能还不能完全分清楚什么是他“必面要的”,什么是他“想要的,最好有的”,但这没有关系。
Tasks:
组建建模团队 |
项目管理 |
必须 |
建模团队是由来自于领域以及开发方面的永久性人员组成。在建模的过程中也可以从其它项目中人员以便有更多的人可以参与并对模型进行评估。 |
||
领域分析 |
建模团队 |
必须 |
领域专家对问题域进行介绍,此过程可能是20分钟也可能是几个小时,需根据具体的问题域情况决定。在介绍时所涉及的内容应比问题域稍大一些。 |
||
学习资料 |
建模团队 |
可选 |
学习各种资料,包括:组件模型、传统的或者是采用use-case方式描述的功能需求书、数据模型以及用记手册。 |
||
生成非正式的功能列表 |
系统设计师 主要程序员 |
必须 |
建模团队生成非正式的功能列表,至于具体的细化和完善留到下一阶段进行。如果需要的话,应将有关的参考资料一并注明。 |
||
开发子模型 |
划分为小组形式的建模团队 |
必须 |
系统设计师提出最初的组件或者是入手点。根据对问题域的理解,小组使用原型及组件创建出类图。创建过程如下:首要关心的是类以及它们之间的关系,然后是类所包含的函数,最后才是类所具有的属性。在寻找类的函数的过程中可以参考对问题域的理解,最初的功能列表,以及原型中所建议的函数等方法。同时还需要生成一个或多个非正式的序列图。 |
||
开发模型 |
系统设计师 建模团队 |
必须 |
记录候选模型 |
系统设计师 主要程序员 |
必须 |
记录员(可以由团队人员分别担任)记录下来工作中所评估过的比较重要的但未被采用的模型,以便于将来在项目中参考。 |
Verification:
内部及外部的评审 |
建模团队 |
必须 |
参与此项目的领域专家进行内部自评,外部评审是必须的,以便判断对问题域的理解是否正确,功能是否是必须的,范围是否合理。 |
Exit:
结束过程时,团队必须提交如下内容,并且这些内容已经过开发经理以及系统设计师的审阅及批准:
- 类图,包括:类、类间关系、类的函数以及属性。类及类间关系建立起了模型的大致轮廓。根据最初的功能有列表以及非正式的序列图而来的函数展现出系统的功能,并且是后续开发过程中建立详细功能列表的前提。此外还应有非正式的序列图。
- 非正式的功能列表。
- 其它可供选择的模型信息。
在此阶段,团队标识出所有的功能,对其加以分组,为其设定优先级,并设置相应的权重。
在下面的活动中,小组工作的重点在于功能,因此领域专家可以不再需要。
Entry Criteria:
建模团队已成功地完成了FDD第一阶段的工作,开发出了系统的整体模型。
Tasks:
组建功能列表团队 |
项目经理 开发经理 |
必须 |
功能列表团队是由来自于领域专家以及开发方面的固定人员构成的。 |
||
标识功能 创建功能集 |
功能列表团队 |
必须 |
团队首先从上一阶段得到的非正式的功能列表入手,接着: - 将模型中的函数转换为功能 - 将模型中的moment-intervals转换为功能集(并将功能集再组织成主功能集),头脑风暴,选择,添加功能以便实现用户所要的以及所想的。 在此采用下述格式进行描述: - 针对功能: <action>the<result><by | for | of | to>a(n)<object> - 针对功能集:<action><-ing>a(n)<object> - 针对主功能集:<object>management 此处的object可以指一个人、一个地点或者一件事(包括:角色、某一时刻、某一时间段或者是描述) |
||
为功能集以及功能设置优先级 |
功能列表团队 |
必须 |
通过“Feature Board”为功能集以及功能设置优先级。优先级的划分:A(必须实现),B(最好能实现),C(如果可能则实现),D(以后再实现)。设置时是依据用户的满意程序所定的。 |
||
分解复杂功能 |
功能列表团队 |
必须 |
在系统设计师的带领下开发人员对功能进行查开,以便找到那些无法在两周之内完成的功能,对此类功能应将其细分为更小的功能或步骤。 |
Verification:
内部及外部的评审 |
功能列表团队 |
必须 |
参与此项目的领域专家进行内部自评,外部评审是必须的,以便判断对问题域的理解是否正确,功能是否是必须的,范围是否合理。 |
Exit Criteria:
本阶段结束时,详细的功能列表必需已经产生了,并且将功能进行分组形成主功能集以及功能集,此外这些内容已经过开发经理以及系统设计师的审阅及批准。
根据已制定的层次化的、具有优先级以及权重的功能列表,项目经理、开发经理以及主要开发人员一起制定出DBF/BBF阶段的里程碑。
Entry Criteria:
功能列表团队已成功地完成了FDD第二阶段的工作,并已形成详细的功能列表。
Tasks:
计划制定团队 |
项目经理 |
必须 |
计划制定团队由项目经理、开发经理以及主要开发人员给成。 |
||
制定功能以及功能集的开发顺序 |
计划制定团队 |
必须 |
计划制定团队设置开发的先后顺序,并制定出最初的针对功能集或者主要功能集的完成日期。 |
||
为类指定实现人 |
计划制定团队 |
必须 |
根据开发顺序以及功能的重要性为每个类指定特定的实现人。 |
||
为主要功能集以及功能集指定相应负责的主要设计人员 |
计划制定团队 |
必须 |
根据开发顺序以及功能的重要性为每个主要功能集或者是功能集指定相应负责的主要开发人员。 |
Verification:
内部及外部的评审 |
计划制定团队 |
必须 |
参与此项目的计划制定人员进行内部自评,外部评审是必须的,并且是由更高一级的管理人员进行。采用“由顶向下”的方式让所有的开发人员均对此计划进行评估。通常一些开发人员由于过分保守会希望延长开发时间。但另一方面,项目经理或者是开发组长又会觉得“每个人都具有与我相同的能力”从而认为可以提前完成开发。在此应进行相应的平衡。 |
Exit Criteria:
本阶段结束时,开发计划已经产生了,并且这些内容已经过开发经理以及主要设计师的审阅及批准。计划中应包括以下内容:
- 一个整体的开发日期
- 针对每个主要功能集、功能集、功能指定有关负责人(CP)以及完成时间
- 针对每个类,指定负责其完成的开发人
注意:
为便于为功能设置优先级,可以创建一个称之为FFB(待实现功能板)。
根据已制定的层次化的、具有优先级以及权重的功能列表,项目经理、开发经理以及主要开发人员一起制定出DBF/BBF阶段的里程碑。
Entry Criteria:
计划制定团队已成功地完成了FDD第三阶段的工作。
Tasks:
组建DBF团队 |
主要程序员 |
必须 |
主要开发人员从已有的类中找与可能与特点功能有关的类,然后找到负责实现这些类的开发人员并将他们组建成功能实现团队。开始进行功能的设计,如果需要的话,还可以请领域专家加入。 |
||
问题域学习 |
功能实现团队 领域专家 |
可选 |
(本步骤是可选的,主要依赖于功能的复杂性而定)领域专家将对问题域进行一个一般性的介绍,他只介绍与功能有关的内容,但这并不是为理解与功能有关的上下文所必须的工作。 |
||
学习有关参考资料 |
功能实现团队 |
可选 |
(本步骤是可选的,主要依赖于功能的复杂性而定)根据功能列表中所列的参考书目以及其它的可拿到的资料,功能实现团队的成员进行学习,以便获得与功能相关的详细的信息。 |
||
创建序列图 |
功能实现团队 |
必须 |
根据对功能的理解以及原有的非正式的序列图和组件,功能实现团队创建一正式的,详细的序列图。同时应记录下可选择的其它方案、决定以及注释。主要的开发人员将序列图添加至项目模型中(同时也要更新相应的类图)。 |
||
实现类及其方法的原型 |
功能实现团队 |
必须 |
每位类的实现人员根据序列图更新有关类及类中的方法,这包括:方法的参数、返回值、错误处理以及消息的发送。 |
||
设计复查 |
功能实现团队 |
必须 |
功能实现团队完成对设计的复查。如果主要开发人员认为有关功能的设计比较复杂并对其有所担心的话,他可以从别的地方请若干人员一起进行复查。 |
||
记录设计复查活动 |
文档人员 |
必须 |
团队中的文档人员针对类的实现人按顺序将有关设计复查的活动记录下来。 |
Verification:
设计复查 |
功能实现团队 |
必须 |
功能设计团队通过对序列图的“走查“实现内部的复查。外部评审是必须的,以确保存有关功能均以实现。 |
Exit Criteria:
本阶段结束时,应已完成如下工作,并且这些工作已经过主要设计师的审阅及批准。计划中应包括以下内容:
- 功能及其相关参考资料(如果有的话)
- 详细的序列图
- 更新后的类图
- 更新后的类及其方法原型
- 开发团队认为有价值的其它实现方案
在DBF工作的基础上,每个类的实现者完成类的各个方法。此外他还需完善基于类的测试方案并实现类一级的单元测试。根据主要开发人员的意见,功能实现团队可能还需在进行单元测试之前先进行源代码检查。当代码编写并检查后开发人员就将其放入配置管理系统中。在所有的类均已完成并Check-In之后,主要开发人员将代码提升以便进行构造。
Entry Criteria:
功能实现团队已成功地完成了FDD第四阶段的工作。
Tasks:
实现类及其方法 |
功能实现团队 |
必须 |
根据DBF中的详细的序列图类的实现人员完成类的方法的实现。此外他也要为测试实现有关的测试方法。主要开发人员则需添加针对功能的测试方法。 |
||
代码检查 |
功能实现团队 |
必须 |
主要开发人员负责安排一次针对BBF的代码检查,检查可以在单元测试之前也可以在其后。一般检查是由功能实现团队成员加以完成的,如果主要开发人员认为需要的话,也可以请团队以外的人进行检查。 |
||
代码检查记录 |
文档人员 |
必须 |
团队中的文档人员针对每个类的实现人将有关的代码检查活动记录下来。 |
||
单元测试 |
功能实现团队 |
必须 |
每个类的实现人员均需测试相应的类的代码以及此类所支持的功能。作为所有功能的集成者,主要开发人员对整个功能进行测试。 |
||
Check-In代码并对其进行构造 |
功能实现团队 |
必须 |
代码一旦编写完成并经过检查和测试,类的实现人就可以将其放入配置管理系统中。当所有的类均已完成Check-In并且可以正常工作时,主要开发人员将提升代码以便进行构造,同时更新在功能列表中的有关功能的状态信息。 |
Verification:
代码检查及单元测试 |
功能实现团队 |
必须 |
功能实现团队必须进行代码检查。文档人员应记录有关活动。 |
Exit Criteria:
本阶段结束时,应已完成如下工作,并且这些工作已经过主要设计师的审阅及批准。计划中应包括以下内容:
- 实现了类的方法并对代码进行了检查和单元测试
- 按顺序针对每个类的方法的单元测试记录
- 类已被开发人员Check-In,主要开发人员已提升代码进行构造并同步更新功能状态。