来自于项目甲方,还是直接或间接的用户、经理、高级经理、操作人员、支持人员、测试人员,与你的系统有联系的其它系统的开发人员,或是维护人员?这是所有的正式需求的来源吗?事实上,提供需求、解释需求、指定需求和排列需求优先级是项目甲方的职责所在。此外,项目甲方有权利要求开发队伍投入时间去辨别和理解这些需求。要想以这种轻巧建模的方式获得成功,理解这个概念是非常重要的。项目甲方负责提供需求,开发组负责理解和实施。
这是否就意味着你可以坐等你的项目甲方来告诉你他们需要什么呢?当然不是。针对他们所告诉你的内容,你可以提出问题,进行分析,促使他们给出更具体的内容,甚而至于可以提出你自己的见解使之改变初衷。你可以建议增加一些新的需求,请注意你所提出的仅是建议,他们可以考虑作为正式的需求加以接受(可能会作出修改)或拒绝。为了找出潜在的需求,你应该经常与甲方保持联系,并借助于一些已有的文档,比如公司政策法规、以前的系统,或者公开的可用资源,比如web上的信息、书籍、杂志或你竞争对手的产品和服务。再次声明,你的项目甲方是需求的最终决定者,而不是你。我不能不强调这一点。
那么项目甲方又从哪里知道他们的需求呢?“我真希望我能这样做”,他们经常会这样抱怨现有的系统,因为他们的竞争对手能做到,但他们却不能;或者想避免过去所出现的问题;或者仅仅是想多增加一个新的功能。一些甲方,尤其是操作人员和高级IT部门经理,可能需要集成现有或即将上马的系统;或者由于某项(象必须削减计算机数量)政策而带来的需求。值得注意的是你的项目甲方应该基于大量的依据明确地阐明需求,而这些依据是应该存在的,你可以通过与之交流确定这一点。
我的经验告诉我在项目中邀请相关方面的专家的加入对找出潜在的需求是很有价值的。例如构建一个电子商务系统,我会邀请有国际化软件设计经验的人员、税法专家或者供应专家的加入。当你对系统中的某些方面不熟悉时(有可能这是你首次构造面向世界各地用户的电子商务系统),这个方法尤其有效。我经常会邀请一些外部的专家和几个甲方在一起交流一两天,来帮助我们检查是否由于我们的经验欠缺而遗漏了什么。这对于确保我们的系统是否完整是一个很重要的方式,特别是在最初定义项目所应包括的范围。这同样也能够帮助甲方进一步的思考。但是,你意识到其中存在危险吗?你所邀请的外部专家提出一些建议可能听上去是非常好的,但目前根本就用不上的。换句话说,你依然得从这些专家意见中精挑细选。
一些基本原理项目甲方的积极参与对构造需求是非常关键的。实际操作中要做到这点存在着两个问题:第一,甲方自身的提供需求的能力以及他们(或者你)是否愿意积极地参与进来。从我的经验来看,一些项目组并没有足够的途径与甲方联系(或不知道甲方在哪),这完全是项目组自身的问题。你的项目肯定有资金,不是吗?这些资金一定是来自于以某种形式存在的项目甲方,所以他们是确实存在的。同样,用户也是肯定存在的。即使你的系统是面向大众,也至少存在着潜在的用户,你可以找到他们,同他们交谈。所以一定存在着你可以向之询问的人。你可能会说,“有时要找出这些人有一定困难”,“要让他们参与进来不是很好办”。是的,确实存在这样的难处,想办法克服它。在“解决需求分析建模中的常见难题”一节中我谈到了一些解决办法,包括没有足够的途径与甲方联系的问题。我的原则是,如果你的项目甲方不能或不愿意参与,这就意味着你的项目失去了内部支持这条成功的条件,因此你要么解决这个问题要么干脆取消这个项目,以减少损失。如果你听之任之,至少你不能宣称使用的是灵巧建模(Agile Modeling)的开发方法(甲方的积极参与是其中的一项核心内容,在AM的开发方法中必须实施)。
那怎么才算项目甲方积极地参与进来了呢?图1使用UML活动图(UML activity diagram)大体上描述了需求阶段的流程,标示出开发人员与甲方各自应承担的任务。图中的虚线把这两部分任务分开来。从图中可以看出有一些任务是共同承担的,如想法或建议的确定(identifying ideas or suggestions)、潜在需求的讨论(discussing a potential requirement)、建模(modeling),可能还有文档的开发(potentially documenting)。项目甲方单独负责指定需求的优先级,系统是为他们开发的,这当然是他们的责权所在。同样的,开发人员负责估计实现这个需求所需的资源,因为他们是实际工作人员。如果自己不作估计而采用来自于项目组外部的估计,这是不合理的也是不可取的。虽然需求的优先级确定和估算超出了AM的讨论范围,但是你可以在如XP和UP这样的软件流程(Software Process)中找到它,理解它们对于整个需求分析是很重要的。AM并不是一个软件流程,它只是应用于这些软件流程中的一种建模方法。
我的观点是:项目甲方应该加入需求的建模和文档开发中来,积极地参与,而不仅仅是提供信息。为达到这点,肯定需要开发人员对甲方进行培训、导引和指导,这是完全可能做到的。我曾经见过一些刚起步的小公司、大企业和政府机构中的甲方能够以非常高的效率建造需求模型以及将这些需求文档化。在电信业,在金融业,在制造业,在军队里我都看见这样的人存在。为什么这点这么重要?因为你的项目甲方才是需求的真正专家。他们知道他们想要的是什么(参见“解决需求分析建模中的常见难题”,如果他们不知道)。而且只要你愿意,他们是能够学会如何建造需求模型和将它们写下来(译注,这样你们之间就可以同一种语言进行沟通)。从轻巧的观点看,这是很有意义的,因为有更多的人将会分担需求建模的工作。
为了让项目甲方更容易地参与进来,消除行业术语方面的障碍,你应该遵循使用最简单的工具这一做法。表1列出了许多需求阶段的artifact,他们都可以用简单或复杂的工具得到。对于每一种artifact,表中都给出了对应的简单工具。图2和图3是使用简单工具的两个例子。图2表示的用粘贴纸针模拟出一个显示界面。图3是使用索引卡片建立概念模型的例子。当你在需求分析阶段引入新的技术时,比如一些可以制作很好的使用案例图的绘制工具或有强大功能的CASE工具,这就会使得你的项目甲方很难加入进来。因为他们不但要学习建模的技术,而且还要学习如何使用这些工具。使用越简单的工具,进入的门槛也就越低,由此你才有更多的机会去增进相互之间的有效协作。
3 两个CRC卡片
我坚信需求的建立是独立于技术的。面向对象的需求、结构化的需求、基于组件的需求,这些都属于实现技术的范畴。虽然你可以选择某种技术来分析需求建立需求,但必须牢记你所真正关心的是需求本身。下面所讲的所有技术,你可以选择其中一种或几种来进行需求建模的工作。
但有时你又不得不抛开“建立与技术无关需求”的想法。比如一个很普遍的限制就是大多数的项目可以从已有的基础技术上获益。在这个层次上,需求仍然是独立于技术的。但如果你仍执著要抛开已有的一些基础技术,比如某个版本的Sybase数据库或要与SAP R/3给出的模块集成,而非得从最底层开始,那就过头了。只要你知道你在做的是什么就可以了,但不要经常性地这样干。
记住从小事做起。越小的需求(象特性(features)或者用户故事(user stories)),相对于越大的需求(象使用案例(use case))就越易于估计和实现。平均的来说,一个使用案例涵盖的功能要多于一个使用情景,这就是“大”的含义。
对于需求跟踪表(requirements tracebility matrix)的使用也需要三思而后行。跟踪能力是指能够由项目进行中所生产的某个artifact的某一方面追踪到另一个与其相关的artifact,而需求跟踪表就是用来记录这些关联关系的。它从每个需求为起点,可以追溯到所有与之相关的分析模型、架构模型、设计模型、源代码或者测试用例。使用跟踪表的组织为了保证各个阶段artifact(包括跟踪表本身)的一致性,必须要经常进行更新工作,而不是仅在受到影响时才改动。使用它的好处是你可以很容易地分析出系统中的哪些部分将会受到该需求改变的影响。但是,如果你有一两个熟悉系统的人(译注:当然你得留住他们),当系统需要改变时,通过他们来进行评估影响会更容易而且费用也会更低。在我看来,给予跟踪表的评价过高了,因为维护它所带来的开销远大于所得到的好处,即便你有特殊的工具去做这件事情。让你项目的管理层认识到它真正的价值和代价所在,让他们来作决定是否使用它。毕竟,跟踪表是一份有效的文档。他们可以据此做出决定。
需求的类型我认为需求可以分为两类:行为类型的(behavioral)和非行为类型的(non-behavioral)。行为类型的需求描述的是用户如何与系统交互(用户界面)、如何使用该系统(用法)、或者是系统如何实现一个业务功能(业务规则)。非行为类型的需求描述的是系统的技术方面,典型的如可用性、安全性、性能、互用性、可信度和可靠性。要注意的是这两类需求有时并不一定能够完全分开来。对存取数据速度的性能要求明显是技术方面的需求,但它也会反映为用户 界面的响应时间,从而影响到可用性和某些用法。访问权限管理,比如谁能够获取特定的信息,这明显是一个行为类型的需求。但它也同样涉及到安全性这个非行为类型的需求。别紧张,不要死揪住这类问题。关键的是能够确定和理解所给出的需求。如果你把一个需求分错了类,谁又会真的去关心呢?
可能的需求分析的artifact由于存在几种类型的需求,有可能其中一些或全部适合于你的项目;又因为每种模型都有长处和缺点,你应该综合利用这些模型,取长补短,以发挥最好的效率。表1列出了一些常用的需求分析建模的artifact,更详细的描述可见Artifacts for Agile Modeling 一文。表中的“简单工具”一栏指出生成相应artifact所常用的简单工具(使用简单工具的重要性在“一些基本原理”一节中讨论过)。
artifact
类型
简单工具
描述
业务规则定义Business rule definition
行为类型
索引卡片(Index card)
业务规则是软件必须满足的一条有效的原则或政策。
变化案例
change case
两者之一
索引卡片(Index card)
变化案例常用来描述新的潜在的需求,或对已有需求的修改。
CRC模型
CRC model
两者之一,通常是行为类型
索引卡片(Index card)
CRC模型是一组标准的索引卡片。每一张卡片被分为三个部分,分别是类的名称,类的职责,以及该类的合作者。类是一类相似对象的抽象,职责是该类所知道的或要去做的,合作者是另外一个与该类有交互的类。在需求建模过程中,CRC模型用在概念建模中,用来揭示某一领域内的概念和它们之间高层的关系。
约束定义Constraint definition
两者之一
索引卡片(Index card)
约束是对你提供解决方案的自由度的限制。把约束作为全局的需求对你的项目来说是很有效的。
数据流图
Data flow diagram(DFD)
行为类型
白板
数据流图展现系统中数据在处理过程间、实体间、以及数据存储站间的流动情况。它常用来描述系统的环境,指出与你的系统相交互的主要外部实体。
基本用户界面原型Essential UI prototype
两者之一
粘贴纸
基本用户界面原型是低精度的。它表现的是界面背后的大致想法,而非细节。
基本使用案例Essential use case
行为类型
纸张
一个使用案例(use case)就是针对一个参与者(actor)的一连串动作,通过使用案例可对该参与者的价值进行测量。基本使用案例是一个简化了的、抽象的、一般化的用案例。它以与特定技术和实现无关的方式攫取一个使用者的意图。
特性
Feature
两者之一,常用于行为类型
索引卡片(Index card)
从用户的角度来看,特性是一个小的、有用的结果。一个特性是可以用于计划、报告和跟踪的一个计量单位。它是可理解的和可衡量的,可以在两个星期内完成(同其它几个特性一起)(Coad, Lefebvre, &Deluca, 1999)。(译注:一个特性在大多数情况下等同于一个功能)
技术方面的要求
Technical requirement
非行为类型
索引卡片(Index card)
技术上的要求是属于系统中非功能性的部分,比如性能上的问题、可靠性的问题或者技术环境方面的问题。
使用情景
Usage scenario
行为类型
索引卡片(Index card)
一个使用情景通过一个或多个的使用案例或用户故事描绘一条单一的逻辑路径。一个使用情景可以表示一个使用案例中的基本路线,即愉快路径;或者该使用案例中的其它路径;或者一条跨越几个使用案例或用户故事的路径。
使用案例图
Use case diagram
行为类型
白板
使用案例图由一些使用案例、参与者和它们之间的关系组成。或者还会有一个系统边界盒。建模时,数据流图用来描述系统的环境,指出与系统相关的主要外部实体。
用户故事
User story
两者之一
索引卡片(Index card)
一个用户故事就是你与项目甲方进行的一次谈话的备忘录。它是高层次的需求,包括行为需求、业务规则、约束和技术要求。
表 1 可选的需求建模artifact
应该注意的是,并不意味着你需要将所有上面所列出的都用在任何一个项目中。熟悉你的模型这条原则(见The Principles of Agile Modeling一文)说的就是你要知道每个artifact适合在什么时候用。你对模型了解得越多,就越能够根据实际情况运用正确的artifact。
artifact的选择往往被所采用的底层软件开发流程所左右。在主页上,我简要地说明了AM与其它有着完整生命周期的软件开发流程一起使用的情况,比如XP或UP。通常不同的底层软件开发流程对需求分析artifact有着不同偏好,象XP使用用户故事而UP用使用案例。这也是你在为需求建模时应该考虑的问题。详细内容请参见AM and XP和AM and UP。
以使用为中心的方法如何在一个商业应用中以灵巧的方式为需求建模呢?让我们来看下面的例子。在这个例子中,我们要为一个SWA Online的系统建立需求模型。在开始之前,读者必须认识到几个问题。第一,因为本文主要集中在需求建模的讨论上,如涉及到其它类型的建模,如分析建模、构架建模或设计建模,我会就此打住并给出我所著的相关文章的连接。灵巧方式的软件开发是高度反复的过程,由此实际上需求建模与其它类型建模的界线不是很明确的。第二,这里所讲的只是许多可用方式的一种,其它的方式也可能是灵巧的。记住,AM是一套基于实践的方法,它没有定义特定的,规范的一种做法,因此可采取的方式是多样的。不用担心,我会在过程中给出我可能会采用的另外的方式,但这也不是所有的 -- 保持你开放的思维。第三,由于SWA Online的开发小组采用的是Enterprise Unified Process(EUP)(Ambler,2001b)开发流程,那么使用案例就会起主要的作用。反之,如果采用的是eXtreme Programming(XP)(Beck,2000)的话,用户故事就会占主导地位。我在AM and XP一文中从XP的角度重新讨论了这个例子。第四,这个例子虽然是基于我的实际经历所虚构的,但我想这会使我们的讨论更加形象而简单。第五,最好将需求建模化分为两个不同的阶段:需求初始阶段(initial requirement up front(IRUF))和详细需求建模阶段。
需求初始阶段(IRUF)需求初始阶段(IRUF)发生在整个项目生命周期的开始,对应于Rational Unified Process(RUP)(Kruchten,2000)中的Inception phase和XP中的第一个迭代之前。它有三个主要的目的:第一,至少从高层次上确定系统的范围,以明确你所要做的工作的范围;第二,定义系统的高层需求;第三,对于需求的含义,在甲方和开发项目组间取得一致。如果你和项目甲方在同一个地点,而且他们能就该系统应该做什么达成比较一致的意见,这个阶段可能只需要几个小时;否则的话,有可能会延长至几天或数周(参见“解决需求分析建模中的常见难题”一节)。你可能需要召开一个大的建模会议,主要是实现需求初始阶段的这三个目的。这些会议有如下特点:
§ 时间长。对一个大的项目可能需要几天。
§ 有许多项目甲方参加,以便广泛地听取他们的需求。
§ 趋向于比较正式的形式(主要由于参加会议的人数众多,而且项目甲方对哪些灵巧的方式并不熟悉)。
§ 包括一些开发人员。尤其是当你开始想让项目组理解该系统是完成什么样的功能时。
系统范围的定义可能用一句话就够了,对SWA Online就可以简而言之为“通过互联网向客户出售产品”或者详细一点的如“在美国本土向新老客户出售有形的而非虚拟的产品”。系统范围同样可使用环境模型(context model)来定义,该模型表示你的系统如何适应所有的环境。它经常使用使用案例图进行表示,参见图5;或用数据流图(DFD),参见图4(常叫做level-0 DFD)。搞清楚系统的范围非常重要,只有这样才能限定你的开发工作。上面的第一句话过于笼统,它可能意味着面向的是国际上的客户,明显这比仅针对美国本土客户的工作量大很多。同样,出售虚拟产品如在线音乐需要另外一套在线交付系统的支持。随着时间的推移,这个范围有可能由于甲方的决定的改变而变化,所以时刻准备好迎接变化。
那么哪一个最适合描述系统范围呢?一句话,DFD,还是使用案例图?根据你的情况而定。语句直接了当,但不如图形的内涵丰富。图4的DFD以所要建造的系统为中心,表述了其与其它外部实体(组织、人或其它系统)的关系,这些外部实体超出了你的系统的控制范围但与你的系统有相互作用。这种方式的主要优点是它以合理的细节描绘了你的系统与外界间的主要信息流动。图5的使用案例图同样以所要建造的系统为中心,以及与该系统有交互的参与者(组织或人)。它的主要优点是描绘出与系统有交互的外部的和内部的参与者,而DFD仅有外部的。主要的缺点就是它没有给出任何一点系统与参与者交互的细节。你应该使用哪一个呢?他们都有各自的优缺点,你可能会考虑都使用。嗯… …?这对我而言不是很灵巧。一个较好的解决办法就是稍稍违反一下规则,结合这两种方式优点仅生成一个图,就象我在图6中所作的。注意一下我的风格:在两个实体的左上角用“I”表示出这是内部实体;移去了DFD中的数字标识符(数字标识符难于人工维护),我宁愿遵循一定的规则以使实体的名称唯一,在需要时这个唯一的名称可以起到标识符的作用。虽然我选择了显示数据流而不得不打破一些使用案例图的规则,但我仍然能够轻易地使用使用案例图的符号。幸运的是我的项目甲方喜欢DFD,我也就投其所好了。记住有目的地建模这条原则就是要你了解你的听众,选取最适合他们的artifact。
不要害怕打破规则。一般经验告诉我们不要在level-0 DFD中包含内部实体,引入内部实体意味着你开始挖掘细节。但我之所以在这里却选择了这样做,是因为它能让我不用再画第二张图。我不会因此而死到临头,也不会招致建模警察的控诉。是的,我违反了应用建模标准这一条做法,但这样做我减少了开发和维护的费用。当这对于某些人成为一个很大的问题时,我想我的组织可以重新考虑一下标准。
为了确定系统的高层需求,我推荐采取基于使用的方法, 即注意力集中在用户如何利用该系统工作这一点上。根据我的经验,这是一个对绝大多数的软件开发都有效的方法。如果你对用户如何使用系统没有一点概念,很难想象你所生产的软件能够支持他们的工作和改善他们的工作方式。我会将这个方法用在建立组织内部使用的商业应用,由客户所使用的商业软件,包装出售的软件(如CASE工具或文字处理软件),数据仓库的开发,甚至于集成现有的商业系统(COTS)如SAP R/3或Oracle Financials。在数据仓库系统的开发中,存在着一个普遍的错误,那就是首先收集“数据需求”。罗列出用户想存储在数据仓库中的数据元素或数据实体。乍看上去,这是个好主意,但如果你不知道用户如何使用这些数据,那么你很难定出优先级或者你根本就不清楚你所做的是否就是甲方所想得到的。对于COTS系统,你需要根据需求来选择使用何种建模方式。如表1所列出的有特性(Feature)、使用情景(Usage Scenarios)、使用案例(Use Case)和用户故事(User Stories),这都是比较好的方式。根据使用恰当artifact这一条,我会选择使用案例,因为SWA采用EUP作为软件开发的主要流程,而使用案例是最适合于这个流程的。如果他们选择的是XP,则用用户故事为佳。如果为Feature Driven Development(FDD)(Coad,Lefebvre,Deluca,1999),那特性就是我的选择。
图7是一个高层的使用案例图,它是一张数字照片,来自于我和我的项目甲方讨论时在白板上所画的图。这是一个基本使用案例图(Constantine & Lockwood, 1999; Ambler, 2001a),因为它以技术无关的观点来显示系统。基于这张图,你既可以全手工的方式来实现这个系统,也可以建造一个全自动的系统。其中的一个使用案例“Post Product Review”可以改名为“Write Product Review”以使之更趋于一般化,但我的项目甲方更偏爱前者。我一直在为尽可能地使需求无关于特定的技术而努力,但事实上许多系统已经局限于某个领域内。例如,SWA Online被限定为基于互联网的解决方案之上,此时如花费精力去尝试将其抽象出来,只会得不偿失。记住保证甲方的投资获得最大利益这条原则,将你的精力集中在能带来效益的那些需求模型上。
使用案例应力求简单,在初始阶段(IRUF)对每个案例有一点提纲挈领式的逻辑描述就足够了。你不必在此时进行细化,你仅需要对该系统的用途有个基本了解,确定初始的范围,再对每个使用案例和参与者加一点提纲挈领式的描述。如果得到项目甲方的认可,你就不用花费更多的精力在初始阶段。可能三到四个使用案例就足够了。然后遵循有目的地建模这条原则,我们就可以终止初始阶段的工作,进入到详细建模阶段去建立详细的模型和实现你所确定的这些需求。注意这种方法更多地是运用在实行XP的项目中,而非实行UP的项目中。
你们可以看见在图7所示的需求图中我使用了UML的构造型(stereotype )<<Include>>,然而在《The Object Primer 2/e》(Ambler, 2001a)一书中我曾建议在分析层次的使用案例图中使用构造型(stereotype),典型的如系统使用案例图,因为它们经常反映了架构和设计方面的问题,而需求层次的使用案例图却并非如此。同样,我也不会因为如此而受到建模警察的控诉。这个图是有意义的,因为它显示出它对处于流程中不同阶段的模型是公共的,在这里它表示我要考虑的包含需求和分析两方面的问题。
要在项目甲方之间达成一致的意见,这说起来容易,作起来难,尽管你有了“解决需求建模中的常见难题”这几招。每个甲方的背景、优先权和喜好都各不相同。为了达成一致意见,每个人都必须认识到这点,相互交流他们需要从该系统中得到什么,倾听他人的意见,准备为了达到一个共同的目标而努力。在我所工作的组中,只要发生意见分歧,我们都会在屋内所有人都能看见的一块白板前写下每人的问题,再进行讨论。这种方式将这些意见的不同之处可视化,可以集中讨论的焦点。在某个问题的提出者认为它不再需要或至少相对于其它问题不那么重要后,我们会将它擦去。虽然有时它是一个较好的意见,但也简单地将之擦去,因为通常我希望记录的是最后的决定。对于两个相互对立的问题,我喜欢在它们之间画一条其它颜色的连线,以突出它们需要进行讨论。
由于我们集中在高层次的使用需求上,相关的业务规则和约束常常也会被同时确定下来。同样,一些技术需求和将来可能或不可能被实现的需求也会确定。在初始阶段(IRUF)你应该将业务规则、约束和技术需求排列出来,常用的方法是将它们写在粘贴纸上或白板上,找出你是否已具备了足够的信息以进行后一阶段的工作。尽快地结束初始阶段的目的是防止你在这个阶段就投入时间探究细节。当你在初始阶段需求讨论会上就进行细节的讨论时,你就给你的项目带来了风险,因为此时你不会收到对你工作的具体反馈,从而陷入分析的泥潭。记住这条原则你的主要目的是软件,而不是那些设想你的软件如何运作的模型和文档。例如在SWA Online的初始需求建模会上,项目甲方提出了一些业务规则和执行顺序的约束,象如何打包某类的货物,某些产品具有一定的上架时间限制,以及分捡流程。当我听到诸如此类的需求时,我就会叫某个人将其写在白板上或索引卡片上,稍后再将这些索引卡片放在每人都能看到的公用桌上。
这里有一个重要的观点:建模会议是交互的,每人都参与其中的。会议的开始需要一个有经验的模型设计者来段开场白,解释一些技术,推动与会者进入状态。这可能就是简单地叫某人走上台来,解释一下正在谈论的内容,演示一下通过填写一张索引卡来总结一条业务规则,或者为一个可能需要的报表在粘贴纸上记录下数据的要求。当与会者熟悉了这种建模方式后,依照灵巧建模的甲方的积极参与这一做法,你会发现不用花太多的精力去鼓励他们的参与。是的,有些人比较开始害羞而需要更多的鼓动,但那毕竟是人的本性(如果我能选择的话,我更喜欢选择那些外向甲方的加入,而非那些内向不愿开口讲出他们意见的人)。
当你的开发组在确定目前版本的需求时,常常伴随着一些后续版本的需求或一些你可能在某时需要实现的潜在需求。虽然此时你不想过多地深究,而且你也不想实现过多的功能去满足这些潜在的需求,但你并不想就此丢弃它们。它们也是有价值的。这些潜在的需求可能会影响到你对系统架构的选择。变化案例(change case)(Bennett, 1997; Ambler, 2001a)是一项用于记录潜在需求的简单技术,图8是SWA Online中的两个变化案例。在定义项目范围时一项重要的工作就是指出哪些需求是现在应该实现的,哪些是超出范围的。变换案例中的需求就是超出当前项目范围的。如何有效地使用变化案例的详细内容可参见Agile Architecture一文。
变化:扩展至北美地区
可能性:非常可能
期限:12-18个月
影响:
§ 必须支持向加拿大和墨西哥的用户交货。与新托运商的关系需要建立。
§ 需要计算相关的税收和关税。
§ 由于法律和当地风俗习惯,在这些市场出售的产品有可能会有所不同。
§ 多语言支持(英语和法语是加拿大的官方语言,墨西哥是西班牙语)。
变化:销售虚拟产品(在线音乐、录像、书籍… …)
可能性:非常可能
期限:6-12个月
影响:
§ 不能与实际产品的运输流程混在一起。
§ 我们可能需要对某些产品支持数字许可。
§ 个别产品的销售可能有某种限制(有效时间、拷贝数量)
图 8 SWA Online 的两个变化案例
那么你需要多少文档来记录项目的范围,初始的、高层次的需求呢?就象我在Agile Documentation一文中所建议的“刚好够用就行”。对于SWA Online这个项目,我们也许建立一个HTML页含图6的环境图,图7的使用案例图,和一个简短的指出范围的列表就够了。为建立高层次需求文档,我会尝试将使用案例转写在一个单独的能进行文字处理的文档上,或者就是一个简单的文本文件。之所以这样做,是因为在详细建模阶段我们要细化它们。有这样一份电子文档使得共享和处理更容易。至于那些记录了业务规则、约束、技术需求和变化案例的索引卡片,让它们保持原样,因为它们会在详细建模阶段得到进一步的细化。我会让我的项目甲方相信,如果我们发现它们确实是需要的,我们会处理的,因为我们那时需要它们。这样由于避免了一些有可能不必要的在文档上的工作(有些业务规则是不合逻辑的,因此在你知道它们的真正价值前所投入在文档上的工作都是浪费),就可以使得开发组能够很快地进入详细建模阶段,然后进入实施阶段。
详细需求建模阶段一旦系统的范围和高层需求得到认同,基于该阶段的成果,你就可以开始为你的开发工作制定进度,将这些需求带进一个迭代过程(iteration)。该计划随着你对需求的理解的不断发展而演化,由此你就开始了真正的开发。
迭代过程的开始在这个过程的开始阶段,这些需求会分发到各个开发者手中。在一个实施XP开发流程的项目组中,开发人员会结成对子,自愿地对给定的用户故事进行处理。每个用户故事都以相同流程得以处理,这个过程不断反复直到处理完所有的用户故事。实施UP的项目组或者以类似的方式运行,或者由项目经理将需求分配给某个开发者或一个小组。无论以何种方式,开发小组/对子都处于实现这些需求的状态。第一步就是要详细了解你的项目甲方想要得到是什么东西,这可能需要进行一些需求建模分析。
在这个迭代过程的开始阶段有两种方式进行建模工作:
集中所有需求在一起进行建模。采用这种方法,整个项目组以及能到的项目甲方会在一起探讨详细的需求,分析这些需求,对已有的系统设计提出修改建议以支持这些需求。假设这整个迭代过程是两个星期,我希望这个会议的持续时间一个小时到半天。如果这个过程更长,假设四到六周,你可能需要花一整天的时间在这上面。这个时间不希望超过一天,因为你不会收到具体的反馈,具体的反馈只有当你用代码验证它时才会得到的。这个方法的优点是可以对所要进行的工作和打算如何去做有一个具体视图,而且可以得到所有项目成员的想法,因此增大了确立一个良好开端的机会。它的缺点就是只适用小项目组,一般少于十个人。而且也比较浪费时间,因为不是与会的每个人以后都要参与各个方面的工作。注意一旦完成了这个初期阶段的工作,每个开发小组仍然需要对它们所负责的部分进行详细的建模。 各个开发小组对它们所负责的需求直接进行建模。有些开发组会在迭代过程的开始阶段放弃以上做法,而简单地就直接让各小组进入到其所负责的部分。这种方式的成功需要有这样的前提:需求间没有联系,或至少联系不是太多;开发人员遵循集体所有制这个做法;基于共有的代码之上。它的优点就是能够使得项目组在迭代过程开始的第一天就进入详细分析建模。但它有几个缺点:第一,当需求映射到设计上有交叉时,可能有两个小组都在处理有关定单计算的问题(比如一个小组负责计算税款,而另一个小组负责折扣的计算),这就会有两个小组工作重叠的风险。但这不算一个严重的问题,因为每个小组都应该知道其它小组正在做什么,当需要时可共同工作。第二,这会经过较长的时间后项目的整个实现视图才会明了。第三,在开始会引起对项目甲方的争夺,因为每个小组工作的开展都需要从他们那里得到输入。 迭代过程中一旦结束了开始阶段的工作后,项目组很快就进入到持续的迭代过程中,建模、编码、测试、编译,或者进行软件配置。你和项目甲方的大部分需求建模的工作会在这段时期中体现,这个过程的目的就是探究、细化这些需求。实际上,更准确地说这些工作就是一些建模会议,因为你可能会不断地重复着需求、分析和设计。这些会议一般是由一小组人即席召开的,一般包括开发小组成员和由一个或几个项目甲方提供输入。这类会议一般讨论某一类别的问题,如“莎利,你能花几分钟时间讲一下客户是如何搜索一个定单的吗?”。
那么我在SWA Online这个项目中是如何进行详细需求建模的呢?首先,假设我们有两个人结成对子。在这个迭代过程中,我们要实现定单的定义和使用案例中“下定单”(Place Order)这个行为的基本路线(basic course of action)中的定购部分。在这里,我们不去实现查找功能,任何类型错误和异常的处理,税金计算和折扣计算[1]。一个行为的基本路线常称为“愉快路径”(happy path),因为沿着这个基本路线所有操作都是正常的、愉快的。行为的备用路线(alternate course of action)是描述当有不正常的操作时所走的路线,这里比如一个用户向一个缺少存货的产品下定单的情况。我们现在仅关心“愉快路径”,其它的需求会由其它的小组或者我们在以后处理。
我们要做的第一件事是充实这条基本路线的逻辑过程,如图9所示。同时也进行关于这个使用案例的基本用户界面原型的工作,如前面的图2所示。之所以我们要并行地进行这两部分工作,是因为它们从两个不同方面来解决这个问题。使用案例描述的是用户在下一个定单时要做什么,基本用户界面原型则是构造一个支持该行为的用户界面。请注意使用案例“Place Order”利用构造型(stereotype)<<Include>>调用了另一个使用案例“Search for Item(s)”,见图7。虽然这个功能是该使用案例中的一部分,但我们并不在这里实现它,因为它超出了范围。我们会采用另一种方式来替代,有可能就是直接给出一个假设的查询结果的页面。这个查询功能会在稍后恰当的时候实现(记住,我们使用的是增量的方式)。同样现在也没有考虑任何类型的技术问题,我们会在以后的分析中或设计中决定这些问题。现在我们只是想了解这个下定单的基本过程,稍后(可能就几分钟后)我们才关心实施的细节。对那些我们不会在这个迭代过程中实现的逻辑步骤,比如税款和折扣计算,当我们在编码时会留下接口。
这个使用案例从一个用户选择下一个定单开始。 用户通过另一个使用案例“Search for Item(s)?”来搜索物品。 用户选择一个物品并加入到他/她的定单中。 用户指定他们想购买该物品的数量。 系统通过该物品的单价和购买数量计算出总价。 用户重复第2步到第5步继续订购其它物品。 用户结束向他们的定单加入物品。 用户提供送货信息和付款信息,包括他们的名字、电话号码和邮寄地址。 系统计算定单中所有物品的总价。 系统按照“Calculate Taxes for an Order”这条规则计算适用于该定单的税款。 系统按照“Calculate Discount for an Order”这条规则计算适用于该定单的折扣。 系统显示税款和折扣。 系统加上税款和减去折扣,得出最后的总价。 系统显示该定单的汇总表。 用户验证该定单是否正确。 系统为该定单下计划(参见使用案例“Fulfill Order”) 系统给出一张该定单汇总收据。
图 9 下定单的行为基本路线