介绍一下我的朋友Jane和John。
John是一家大型公司的长期分析师,负责捕获新的软件产品及现有软件产品的需求。他用SRS(软件需求规格说明书)记录所有客户对正在开发或维护的特定产品的需求。
Jane是同一家公司的开发人员。她通常接收John的软件需求规格说明书(SRS),而后开始对要实现的内容进行技术分析和设计。完成分析之后,她就开始写代码实现。
我的这两个朋友John和Jane的需求文档和设计文档都需要经过审批;对于John来讲,把需求文档发给Jane之前需要经过审批,而对Jane来讲,则是在开始写代码之前要经过审批。
最近,John和Jane所在的公司采用了敏捷方法来作项目管理和软件研发,这使得他们的工作方式发生了改变。不需要制定大量的前期需求和设计,需求说明书和开发都被切成了小块的信息,摒弃了使用多年的大篇幅文档。开发人员的开发方式也发生了变化,鼓励像实现之前先做测试设计和用较长的名字来命名函数等这样的做法。
不出所料,John和Jane提出了一大堆的问题:
在过去十年中,敏捷方法在项目管理和软件开发中的应用经历了迅速发展的阶段,并预计将持续地增长。在向敏捷过渡的过程中,看似宽松的开发方式完全不同,做事不再那么传统,为此,世界各地的许多人都会和John、Jane一样抛出如上同样的问题。
当公司开始过渡到敏捷理念的过程中,一些工作方式的差异都与文档有关。
本文将重点讲述为什么、什么时候、如何以及在哪里编制技术和功能文档。
敏捷宣言中宣称的价值观是:
个体和互动高于流程和工具
工作的软件高于详尽的文档
客户合作高于合同谈判
响应变化高于遵循计划
尽管提到了文档,但敏捷原则在如何编制文档方面并没有给出任何刚性的指导原则。
因此,在敏捷管理的项目中我们应该期待产出什么样的文档呢?
敏捷理念背后的原则是,强调为客户实现价值。这就意味着我们应该把产品开发的时间花在能够为客户带来价值的那部分,避免在几乎没有什么价值的任务上浪费时间。该原则也同样适用于文档的编制。
在传统的瀑布方式中,文档是一个预定义的阶段,它需要花费大量的时间。过渡到敏捷则意味着我们必须重新思考编写文档的方式,以避免把时间浪费在价值具有争议的交付成果上。
这是否意味着我们不需要编制任何文档呢?其实不是这样的。
另一个敏捷原则是适应变化。那就意味着我们不能提前做太多的计划,因为事情在项目进行中会有所变化。所以,我们永远专注的是适时的计划。这一条也同样适用于文档。为了避免浪费时间,我们应该只在需要文档时才去编写它。
但是,我们如何知道它何时需要呢?
如果你来自瀑布的领域,那么很自然就会带过来定义大量文档的习惯,但这样会导致:
为了避免这个情况,有一些指导方针帮助我们决定是否真的需要编制文档。
为避免在文档上浪费时间,向每个相关的人问如下问题:
决定是否需要文档的一个关键因素是,只定义正好够用的文档。在干系人真正需要的和完整的内容之间寻找平衡点。不多不少,恰到好处。
对为什么编制文档和编制多少文档达成共识之后,在开始编制之前还需要定义要编制什么样的文档。
根据文档的目标受众来编制相应的文档。教程?培训材料?维护支持文档?业务规则文档?还是系统描述文档?
在项目的每一阶段规定需要什么样的技术文档和功能文档,从而来确定编制什么文档:
在一个易于访问的并可不断更新的资源库中保存文档对保持文档的可用性非常有帮助。用Word文档或类似的格式会让其变得陈旧或过时。
随着项目的滚动进行,文档应当长期保持更新,保持文档对目标受众的有效性。
不像在瀑布式开发所期待的那样,在敏捷开发中没有文档阶段。
因此,当功能以增量的方式开发时,文档的编制也应该是增量的,与产品开发一起演进。
在这一点上我们应该决定:
在项目的每一个阶段如何编制文档呢,现在让我来提供一些建议和最佳实践。
在项目初期阶段,只需要少量的文档,因为真正的工作就是如何开始。
当开始编制技术文档时,定义你选定的两个或者三个高层次的架构图,并定义解决方案中需要实现的高层次组件。
在功能方面,用史诗(Epics)来定义产品需要开发的主要特征就可以了。
因为要用敏捷的方式管理项目,不要求预先设计,所以在这个阶段,定义够用的信息,让团队开始工作就足够了。
在项目进行阶段,随着产品的增量开发,可能需要编制两种类型的文档:
A.恰到好处的需求文档-作为产品待办事项列表(Product Backlog)的输入。
B.要实现的系统和业务逻辑-作为每个迭代的输出。
每一种文档都有它自己的目标受众:
目标受众A:团队。
目标受众B:干系人和最终的维护团队。
这些文档需要对这两类目标受众的需求给出回应。
功能文档
用户故事是敏捷管理项目中最常用的功能文档。用户故事汇聚了足够的信息,告诉开发人员如何实现这些需求,它是用下面的格式描述的:
在迭代计划之前,用户故事的需求描述必须经过干系人的认可,这意味着现在它们已经为计划的迭代做好了准备,它们应该有可靠的信息来源(需求),开发人员知道要实现什么。这需要对目标受众A提供足够的信息。
当用户故事正在开发中时,团队可能会确定新的验收标准,然会添加到用户故事中。
记住,在敏捷中,用户故事不应该是一小块非常详尽的需求描述,而是希望提供什么功能实现的指导方针,这是产品负责人和团队之间未来合作要实现什么产品的承诺。
当用户故事开发完成并被干系人接收之后,那么就可以认为它是已接收的了。这个时候,用户故事需要从Product Backlog(需要实现的一系列功能需求描述列表)中挪到Product Increment(在迭代及所有之前的迭代中已完成的一系列产品代办列表)。
当用户故事以增量的方式完成时,目标受众B所需要的文档在下图1中显示。
技术文档
在研发阶段,开发人员需要运用一些公认的最佳实践(作为敏捷开发方法的一部分),例如测试驱动开发TDD(Test-Driven Development)和行为驱动开发BDD(Behavior-Driven Development),以及结构良好的代码、非技术人员可读等。这个需要提供描述代码的技术文档。
最新的功能和技术文档
因为代码是最新的业务规则和系统实现的最可靠来源,因此基于代码本身是拥有有效文档的最佳方式。
活文档是实现它的一种方式。
活文档或动态文档是持续编辑和更新的文档。活文档的概念依赖于在代码中集成的文档,该文档是基于验收标准,用领域专用语言(Domain Specific Language)来写的,例如用于Cucumber的Gherkin。通过工具来辅助活文档的持续构建,写在用户故事中的验收标准作为代码的一部分已经实现了,并且以一种可读的格式在更新的、典型的在线地址上输出。
提供活文档机制的一些工具包括:Cucumber,Concordion,FitNesse,SpecFlow,
Pickles,以及其他。他们都值得一看。
由于文档是随着用户故事的实现增量编制的,在开发周期结束和产品推出后,那些技术和功能文档应该描述了所有的功能实现。
当决定需要编制多少文档时,很重要一点是要定义多少文档是刚好够用的文档。
图2描绘了本文中所推荐的用来决定文档编制的路线图。
在确定了为什么、做什么、什么时候做、怎么做之后,就要用敏捷的方式定义编制文档的最佳实践,用敏捷软件开发的技术和活文档。
表格1中列出了每一阶段推荐的文档输出内容。
|
项目前期文档 |
项目中期文档 |
项目后期(维护)文档 |
技术 |
选择的两个或三个高层次架构图 |
结构良好的代码,无技术基础人员易读 测试驱动开发 (TDD) 行为驱动开发 (BDD) 以代码为文档 【一次一个用户故事】 |
代码作为技术文档 |
功能 |
主要的史诗定义产品需要开发的主要特征 |
具有定义良好的用户故事,清晰的验收标准 以验收标准为文档 【一次一个用户故事】 |
代码作为活文档 |
如同我的两个虚拟朋友Jane和John所经历的一样,对任何的团队来说从传统的瀑布式到敏捷开发的过渡都是一种挑战。人们的工作方式已经沿用了几十年,当发生转变时,就会引发各种问题和质疑。
在所有这些由团队协作方式的转变(尤其是在思想意识上的转变)而引起的问题和质疑中,文档是一个主要的问题,这是其中变化最大的一个--从开发之前编制所有文档变成同一阶段几乎不怎么写文档。
敏捷的基本原则并没有说不需要任何文档,只是提醒团队应该注重给客户交付的价值。在编制文档的过程中,也应该考虑这一关键原则。
所以,编制文档时请记住,只在需要的时候编制必要的文档,不多也不少。
敏捷并非不写文档,而是重视文档的作用,也重视文档的维护;它认为文档宜少且精炼,不需要冗余的文档;文档也是作为细化部分,在每个迭代过程中不断重构;一般需求文档、概要设计、详细设计、数据库设计、项目管理文档(甘特图等等)都是必须的,在许多外企的迭代开发中都是这样的,倒是国内的公司确实提倡一种:敏捷无文档,开发效率慢,基本的文档都是必须的;敏捷开发中的写文档,有了方向性的指导。
总结:开发要有开发文档(需求文档、数据库设计、概要设计)、开发计划(甘特图、燃尽图)、测试计划(时间、地点、人员、任务模块分配、禅道bug提交管理)都应该有一个时间段,在大家的一起商量之下可以每个人做到心中有数,对任务整体有个全局观,我们每天该干什么?紧急重要的需求?客户迫切需要上线的功能?都有一个好的规划,避免在不必要的文档上(官话、客套话)浪费更多的时间,劲使在刀刃上,提高我们的开发效率,有明确的目标、去按照我们的计划一步步的完成。