中程在线信息产业培训网(www.miiceic.org.cn)
特征驱动开发(Feature-Driven Development,FDD)是一个模型驱动( model-driven)、短期遍历(short-iteration)的过程. 注意,FDD是一个开发过程,过程总是有起点和终点,FDD的起点是起源于创建一个全局的模型轮廓(不要求很精确,大概模样就可以),然后大概是两周的一系列的"design by feature, build by feature"的迭代,逐渐丰富模型功能内容,features是指小的、以软件用户的视角看是有用的特征功能,一个FDD开发过程都下图。

以JiveJdon3.0为例子,它的起初建模是Forum、ForumMessage几个Model,然后我们立即开始开发围绕这些Domain Model的特征功能,这些特征功能一些是以Service形式对外开放的,一些是供内部调用的Manager特征功能,在设计和开发这些Service或Manager时,会反过来修改丰富Domain Model,我们需要分辨哪些特征功能是一种属性Attribute操作,属于属性Attribute的在Domain Model中实现;还要分辨哪些属于Operations行为功能,这些则在Service或Manager中实现,这个过程就是属于下图的“design by feature, build by feature”过程,JiveJdon3.0源码包的大包名主要是Model/Service等,Service相当于分类的特征功能列表,也就是在下图的第二步设计产生的。
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
一、为什么需要特征驱动开发FDD?FDD没有传统工程中冗长的设计过程,而是通过边设计边开发进行迭代完善,因此它非常适合项目的快速开发,由于不断的竞争,现在一个项目的交货周期越来越短,需要在极短的时间内开发一个可维护、可拓展的高质量软件系统已经是形势所逼。
软件开发人员喜欢新的事情,使用FDD每两周就有新的事情可做,而且每两周就可以交货完成一些工作,离目标越来越近,这种 Closure感觉在开发队伍中是很重要的,可以让大家万众一心,有一种拧在一起的冲劲,从而潜在地提高开发人员的积极性。
同时,项目经理也会喜欢FDD,通过FDD,他们能够知道规划什么、以及确立关键开发阶段,经理们可以频繁参与项目协调和管理,同时掌握大家的工作成果,从而了解整个项目完成的百分比进度,例如是完成了57%还是其他数字。
软件系统的客户也回喜欢FDD,他们能够参与或看到开发过程中的关键阶段,能够看见前一阶段的开发结果,以确认和他们要的是否一致,并提出下一步修改意见。
二、特征驱动开发FDD这几个步骤
1. 开发一个全局的模型
在一个有经验的组件/对象建模专家(首席架构师)指导下,业务领域需求人员与开发人员一起协调工作,业务领域人员提供一个初始的、具有一定高度的、可以覆盖整个系统和业务场景的介绍,领域人员和开发人员会依此产生初始的模型,然后再结成单独小组,进入详细继续讨论阶段,将模型轮廓描绘出来,然后丰富之前产生的初始模型。
2. 建立特征列表(Feature List)
当初始模型产生以后,有一个单独小组成员将开始构建复杂的特征(feature)功能列表,特征feature的意思是一段有价值的小功能,体现为下面形式:
the
翻译:什么对象发生了什么结果/什么结果发生在什么对象上/为什么对象发生什么结果/发生了什么的对象的结果。
说白了,就是动作行为的发生,每个动作行为发生都是由一个对象为主体的,例如:计算订单总和;XX数据的增删改查等,当然,需求文档中的用例或功能要求都是可以作为输入为特征功能列表。
从这里我们可以看出,特征feature不同于通常一般意义上的功能function,特征feature虽然也是属于功能,但是它是围绕一个对象模型(Object Model)发生的功能,而不是需求文档中混乱的、没有经过整理的功能列表。
建立特征列表就是将这些功能进行分类、合并和整理,例如功能需求中有:用户注册、用户修改注册资料和用户登录等功能,那么输入到特征功能列表中以后就可能是:围绕对象模型User的新增、修改和删除以及查询等特征功能。
特征功能是一个个从软件用户角度看有价值的结果,注意是短而有用,比如“建立一个用户子系统”就显得需要很长时间才能完成,不够短,而象“建立表现层”就对于软件用户没有意义,他不懂什么是表现层或业务层等技术术语,他更关心他的功能是否完成,所以建立表现层对于软件用户是没有价值的结果,也不属于特征功能。
特征功能是软件用户提出的切实的有效的功能,软件用户知道这个软件干什么用,他会识别它的,小的特征功能是在两周内可理解的、可衡量的、可实现的一些功能。
例如,如下四色图表示了一个特征功能集合:

特征功能集合是:将一个商品销售给一个客户
特征功能是一个个小方法:
计算销售总数
估算完成销售的时间底线。
计算被一个客户购买的总数。
有过JdonFramework等现代框架开发经验的程序员一看就知道,其实四色图中的粉红色MI大部分是使用Service来实现的,或者供内部调用的Manager实现,如围绕Customer模型有CustomerService、围绕User模型有UserService、围绕Message有MessageService等等。
3. 依据特征规划(Plan By Feature)
下一步工作就是将主要的特征功能集合进行排序和计划,然后分配给主要程序员组长,这时,程序员也会跟着他们在全局对象模型中所负责的类进入相应的程序员小组。例如张三开始是参与Message这个Model构建和规划,那么与Message这个对象模型相关的特征功能列表被分类出来并分配到特定程序员小组时,张三也就是跟着进入这个程序员小组。
4.依据特征设计/依据特征构建(Design By Feature / Build By Feature)
当每个程序员小组领到自己的特征功能集合后,召集4-5个程序员开会,组长挑选一小组适合2周内完成的特征功能集合,然后执行 'Design By Feature (DBF)' 和 'Build By Feature (BBF)'. 组长将相应的一些类和特征功能分配给小组Team,特征Team进行详细的顺序图设计, 然后写出类和方法逻辑。
下面是进入依据特征构建阶段,也就是代码的编译调试测试阶段,在进入BBF阶段之前,Team小组要进行设计代码复核,在进入后,类的作者进行类的整合、测试和复核,一旦程序员组长满意,完整的特征功能实现将被提交到主要的Build过程,也就是进入集成测试阶段。
每个程序员组长可以并行负责带领2-3特征小组Team运转,特征小组中任何人任何时候都可以成为类的作者(编写类的具体实现代码)。
三、特征驱动开发FDD与XP区别
FDD非常类似极限编程XP,但是有如下区别:
1、Team的大小:XP设计成2-10人;而FDD设计成16-20人
2、建模方式不同:XP是写Story在一个个Index卡片上,项目所有的人(客户经理和开发人员都能知晓系统是如何工作的);FDD使用domain walkthroughs(业务领域通概介绍)和特征任务来替代Story,最大的不同是,FDD多了一个Domain Model对象的设计和开发,Domain Model成为整个项目的指示灯,就象革命队伍中的宝塔红灯。这可注意:这个Domain Model作用可不小,可以减少误解、驱动开发人员进行更加完整、更加丰富下阶段开发,类似革命航线的引路人。
3、还有更多区别,可见 FDD和XP一文
三、特征驱动开发FDD 过程 #1: 开发总体模型
Entry Criteria:
客户已准备好建立一个系统。他已经有采用某种形式保存的需求列表。此时用户可能还不能完全分清楚什么是他“必面要的”,什么是他“想要的,最好有的”,但这没有关系。
Tasks:
组建建模团队 必须 建模团队是由来自于领域以及开发方面的永久性人员组成。在建模的过程中也可以从其它项目中人员以便有更多的人可以参与并对模型进行评估。 领域分析 建模团队 必须 领域专家对问题域进行介绍,此过程可能是20分钟也可能是几个小时,需根据具体的问题域情况决定。在介绍时所涉及的内容应比问题域稍大一些。 学习资料 建模团队 可选 学习各种资料,包括:组件模型、传统的或者是采用use-case方式描述的功能需求书、数据模型以及用记手册。 生成非正式的功能列表 系统设计师 主要程序员 必须 建模团队生成非正式的功能列表,至于具体的细化和完善留到下一阶段进行。如果需要的话,应将有关的参考资料一并注明。 开发子模型 划分为小组形式的建模团队 必须 系统设计师提出最初的组件或者是入手点。根据对问题域的理解,小组使用原型及组件创建出类图。创建过程如下:首要关心的是类以及它们之间的关系,然后是类所包含的函数,最后才是类所具有的属性。在寻找类的函数的过程中可以参考对问题域的理解,最初的功能列表,以及原型中所建议的函数等方法。同时还需要生成一个或多个非正式的序列图。 开发模型 系统设计师 建模团队 必须 记录候选模型 系统设计师 主要程序员 必须 记录员(可以由团队人员分别担任)记录下来工作中所评估过的比较重要的但未被采用的模型,以便于将来在项目中参考。
Verification:
|
内部及外部的评审 |
建模团队 |
必须 |
|
参与此项目的领域专家进行内部自评,外部评审是必须的,以便判断对问题域的理解是否正确,功能是否是必须的,范围是否合理。 | ||
Exit:
结束过程时,团队必须提交如下内容,并且这些内容已经过开发经理以及系统设计师的审阅及批准:
- 类图,包括:类、类间关系、类的函数以及属性。类及类间关系建立起了模型的大致轮廓。根据最初的功能有列表以及非正式的序列图而来的函数展现出系统的功能,并且是后续开发过程中建立详细功能列表的前提。此外还应有非正式的序列图。
- 非正式的功能列表。
- 其它可供选择的模型信息。
四、特征驱动开发FDD 过程 #2: 创建功能列表
在此阶段,团队标识出所有的功能,对其加以分组,为其设定优先级,并设置相应的权重。
在下面的活动中,小组工作的重点在于功能,因此领域专家可以不再需要。
Entry Criteria:
建模团队已成功地完成了FDD第一阶段的工作,开发出了系统的整体模型。
Tasks:
组建功能列表团队 项目经理 开发经理 必须 功能列表团队是由来自于领域专家以及开发方面的固定人员构成的。 标识功能 创建功能集 功能列表团队 必须 团队首先从上一阶段得到的非正式的功能列表入手,接着: - 将模型中的函数转换为功能 - 将模型中的moment-intervals转换为功能集(并将功能集再组织成主功能集),头脑风暴,选择,添加功能以便实现用户所要的以及所想的。 在此采用下述格式进行描述: - 针对功能: the - 针对功能集:<-ing>a(n)
- 针对主功能集:
此处的object可以指一个人、一个地点或者一件事(包括:角色、某一时刻、某一时间段或者是描述) 为功能集以及功能设置优先级 功能列表团队 必须 通过“Feature Board”为功能集以及功能设置优先级。优先级的划分:A(必须实现),B(最好能实现),C(如果可能则实现),D(以后再实现)。设置时是依据用户的满意程序所定的。 分解复杂功能 功能列表团队 必须 在系统设计师的带领下开发人员对功能进行查开,以便找到那些无法在两周之内完成的功能,对此类功能应将其细分为更小的功能或步骤。
Verification:
|
内部及外部的评审 |
功能列表团队 |
必须 |
|
参与此项目的领域专家进行内部自评,外部评审是必须的,以便判断对问题域的理解是否正确,功能是否是必须的,范围是否合理。 | ||
Exit Criteria:
本阶段结束时,详细的功能列表必需已经产生了,并且将功能进行分组形成主功能集以及功能集,此外这些内容已经过开发经理以及系统设计师的审阅及批准。
五、特征驱动开发FDD 过程 #3: 根据功能制定计划
根据已制定的层次化的、具有优先级以及权重的功能列表,项目经理、开发经理以及主要开发人员一起制定出DBF/BBF阶段的里程碑。
Entry Criteria:
功能列表团队已成功地完成了FDD第二阶段的工作,并已形成详细的功能列表。
Tasks:
计划制定团队 项目经理 必须 计划制定团队由项目经理、开发经理以及主要开发人员给成。 制定功能以及功能集的开发顺序 计划制定团队 必须 计划制定团队设置开发的先后顺序,并制定出最初的针对功能集或者主要功能集的完成日期。 为类指定实现人 计划制定团队 必须 根据开发顺序以及功能的重要性为每个类指定特定的实现人。 为主要功能集以及功能集指定相应负责的主要设计人员 计划制定团队 必须 根据开发顺序以及功能的重要性为每个主要功能集或者是功能集指定相应负责的主要开发人员。
Verification:
|
内部及外部的评审 |
计划制定团队 |
必须 |
|
参与此项目的计划制定人员进行内部自评,外部评审是必须的,并且是由更高一级的管理人员进行。采用“由顶向下”的方式让所有的开发人员均对此计划进行评估。通常一些开发人员由于过分保守会希望延长开发时间。但另一方面,项目经理或者是开发组长又会觉得“每个人都具有与我相同的能力”从而认为可以提前完成开发。在此应进行相应的平衡。 | ||
Exit Criteria:
本阶段结束时,开发计划已经产生了,并且这些内容已经过开发经理以及主要设计师的审阅及批准。计划中应包括以下内容:
- 一个整体的开发日期
- 针对每个主要功能集、功能集、功能指定有关负责人(CP)以及完成时间
- 针对每个类,指定负责其完成的开发人
注意:
为便于为功能设置优先级,可以创建一个称之为FFB(待实现功能板)。
六、特征驱动开发FDD 过程 #4: 根据功能进行设计(DBF)
根据已制定的层次化的、具有优先级以及权重的功能列表,项目经理、开发经理以及主要开发人员一起制定出DBF/BBF阶段的里程碑。
Entry Criteria:
计划制定团队已成功地完成了FDD第三阶段的工作。
Tasks:
组建DBF团队 主要程序员 必须 主要开发人员从已有的类中找与可能与特点功能有关的类,然后找到负责实现这些类的开发人员并将他们组建成功能实现团队。开始进行功能的设计,如果需要的话,还可以请领域专家加入。 问题域学习 功能实现团队 领域专家 可选 (本步骤是可选的,主要依赖于功能的复杂性而定)领域专家将对问题域进行一个一般性的介绍,他只介绍与功能有关的内容,但这并不是为理解与功能有关的上下文所必须的工作。 学习有关参考资料 功能实现团队 可选 (本步骤是可选的,主要依赖于功能的复杂性而定)根据功能列表中所列的参考书目以及其它的可拿到的资料,功能实现团队的成员进行学习,以便获得与功能相关的详细的信息。 创建序列图 功能实现团队 必须 根据对功能的理解以及原有的非正式的序列图和组件,功能实现团队创建一正式的,详细的序列图。同时应记录下可选择的其它方案、决定以及注释。主要的开发人员将序列图添加至项目模型中(同时也要更新相应的类图)。 实现类及其方法的原型 功能实现团队 必须 每位类的实现人员根据序列图更新有关类及类中的方法,这包括:方法的参数、返回值、错误处理以及消息的发送。 设计复查 功能实现团队 必须 功能实现团队完成对设计的复查。如果主要开发人员认为有关功能的设计比较复杂并对其有所担心的话,他可以从别的地方请若干人员一起进行复查。 记录设计复查活动 文档人员 必须 团队中的文档人员针对类的实现人按顺序将有关设计复查的活动记录下来。
Verification:
|
设计复查 |
功能实现团队 |
必须 |
|
功能设计团队通过对序列图的“走查“实现内部的复查。外部评审是必须的,以确保存有关功能均以实现。 | ||
Exit Criteria:
本阶段结束时,应已完成如下工作,并且这些工作已经过主要设计师的审阅及批准。计划中应包括以下内容:
- 功能及其相关参考资料(如果有的话)
- 详细的序列图
- 更新后的类图
- 更新后的类及其方法原型
- 开发团队认为有价值的其它实现方案
七、特征驱动开发FDD 过程 #5: 根据功能进行设计(BBF)
在DBF工作的基础上,每个类的实现者完成类的各个方法。此外他还需完善基于类的测试方案并实现类一级的单元测试。根据主要开发人员的意见,功能实现团队可能还需在进行单元测试之前先进行源代码检查。当代码编写并检查后开发人员就将其放入配置管理系统中。在所有的类均已完成并Check-In之后,主要开发人员将代码提升以便进行构造。
Entry Criteria:
功能实现团队已成功地完成了FDD第四阶段的工作。
Tasks:
实现类及其方法 功能实现团队 必须 根据DBF中的详细的序列图类的实现人员完成类的方法的实现。此外他也要为测试实现有关的测试方法。主要开发人员则需添加针对功能的测试方法。 代码检查 功能实现团队 必须 主要开发人员负责安排一次针对BBF的代码检查,检查可以在单元测试之前也可以在其后。一般检查是由功能实现团队成员加以完成的,如果主要开发人员认为需要的话,也可以请团队以外的人进行检查。 代码检查记录 文档人员 必须 团队中的文档人员针对每个类的实现人将有关的代码检查活动记录下来。 单元测试 功能实现团队 必须 每个类的实现人员均需测试相应的类的代码以及此类所支持的功能。作为所有功能的集成者,主要开发人员对整个功能进行测试。 Check-In代码并对其进行构造 功能实现团队 必须 代码一旦编写完成并经过检查和测试,类的实现人就可以将其放入配置管理系统中。当所有的类均已完成Check-In并且可以正常工作时,主要开发人员将提升代码以便进行构造,同时更新在功能列表中的有关功能的状态信息。
Verification:
|
代码检查及单元测试 |
功能实现团队 |
必须 |
|
功能实现团队必须进行代码检查。文档人员应记录有关活动。 | ||
Exit Criteria:
本阶段结束时,应已完成如下工作,并且这些工作已经过主要设计师的审阅及批准。计划中应包括以下内容:
- 实现了类的方法并对代码进行了检查和单元测试
- 按顺序针对每个类的方法的单元测试记录
- 类已被开发人员Check-In,主要开发人员已提升代码进行构造并同步更新功能状态。