今天准备谈下软件需求分析和开发方面的话题,软件需求是整个软件生命周期中最重要的一个环境,但是我们注意到在当前类似SCRUM等各种敏捷方法论下,软件需求被一再的弱化。
我一再强调,如果仅仅是需求变更,采用类似用户故事这种方式进行需求描述和分解没有问题,但是如果是全新的建设一个大的业务系统,那么软件需求就是一个系统工程,必须要进行完整的业务需求和业务建模。
需求分析和需求建模概述 ???01-需求究竟是什么?
对于业务用户来说,需求就是他们在不同的业务场景下面临的业务问题,或者说他们希望一种解决方法来达成业务目标;而对于技术人员来说,需求就是你需要实现的软件功能。
???因此需求本身是分层的,其包含了业务需求,用户需求,产品需求和功能需求。
??业务需求简单来说就是业务目标和范围。 ?而用户需求是用户必须要完成的工作和任务,希望解决的问题。 ?软件功能需求说明书中的软件需求已经到了具体需要实现的软件功能。 ?不同的角色对需求的理解都不一样,而需求工程师需要做好的就是从业务需求到软件需求的一个关键转化和抽象。
???即通过业务建模来实现了现实世界的抽象化模型表达。
???对于完整的需求工程实际包括了需求开发和需求管理两个方面的内容,如果实施过CMMI过程改进也可以看到,在CMMI里面需求管理和需求开发是两个独立的过程域。
需求开发过程重点就是需求定义和获取,需求分析,需求开发,需求验证几个关键内容。而对于需求管理即包括了需求变更管理,需求追踪,需求版本和基线管理等。
02-需求分析概述
需求分析是需求工程中的核心工作,也是需求分析人员的工作重心。
在通过需求调研活动捕获原始需求后,需求分析人员要以原始需求作为输入,通过需求分析,选择一种业务导向的线索将零散的需求串起来,形成体系完整、内容清晰的脉络与框架,以指导后续的设计、开发工作,并最终将需求分析产出的工件输出给开发团队。
???需求分析就是先分解,再提炼,并在这个过程中消除矛盾。
分解是一种自顶向下的方法,其目的是为了降低问题域的复杂度,通过对问题域的逐层分解,将问题域分解为相对独立的更小的域,从而降低其复杂度,最后分而治之各个击破,得到基于每个分解后域的需求分析结果。
结合原来的需求实践可以看到,在需求分析时,也经常使用了分解的方法:将待构建的目标系统分解为模块,再将模块分解为不同的业务单元,最后基于业务单元分别进行分析并得到需求分析结果。
需求分析的核心内容就是分解+抽象。
???基于分解后的“小块”分别分析后会得到很多的需求分析片段,基于这些“小块”的片段之间可能会存在一些矛盾,比如说可能存在一些重复、冲突或是逻辑上的不完整,要消除这些矛盾,就需要将片段放到更大的上下文中考虑,这是一个自底向上的过程,即抽象与提炼。
03-需求建模
建模的目的是帮助我们按照实际情况或按我们需要的样式对系统进行可视化,提供一种详细说明系统的结构或行为的方法,给出一个指导系统构造的模板,对我们所做出的决策进行文档化。
建模的例子在现实生活中无处不在,比如大家常见的对于建筑物的建模,通过模型建筑师可以在真正建造建筑物前将建筑物可视化,从而可以对现实进行简化及研究,从而使用较小的成本发现并修改问题。
另一方面,模型也是沟通过程中常用的重要手段,试想一下,如果没有模型,建筑师将如何向他人阐明设计理念,销售人员将如何向购买者介绍及推荐?
???同样的,需求建模是需求分析的主要手段,它通过简化、强调来帮助需求分析人员理清思路,对问题域进行研究并最终用于和上游及下游进行沟通。
如果是对于企业级的业务和需求分析,我们可以参考类似企业架构中的需求和业务建模框架,比如企业架构模型中的Zachman框架,其中的企业模型和概念模型很多就属于需求层面内容。而类似TOGAF方法论中的业务架构和数据架构的建模思路,我们常说的ARIS的流程分析和建模方法等都可以作为我们在进行端到端需求流程和需求分析时的重要参考。
??????另外在需求建模过程中,我们总结如下要点需要注意:
建模只是手段,不要为了建模而建模
建筑师对建筑物进行建模,要么是为了验证自己的设计思路,要么是需要希望通过模型进一步研究建筑物以发现问题,要么是希望通过模型向他人传达自己的设计意图,总之,建筑师不会为了建模而建模。
同样的,需求建模也只是需求分析的手段,要带着目的去建模,不要为了建模而建模!
模型有很多种,不同的模型是对现实在不同精度级别的表达
?还是引用现实生活中的例子来讲解:售房人员在向购房者推荐房子时,通常会使用两种模型,其一是立体的模型,其二是房子的平面模型(买过房子的人都知道,就是房书)。立体的模型可以让购房者能比较好地感受到房子的方位,采光以及小区环境等,然而对于房子的布局以及各个部位的尺寸,使用这种模型就不太容易表达,而这正是平面模型的特长。
类似的,需求模型也有很多种,不同需求模型有不同的用处,需要在需求分析过程中根据目标来选择不同的模型。
单个模型是不充分的
通过上面的阐述可以知道,不同的模型有不同的特点,可以在某一或某些方面对问题域进行表达,所以在需求分析过程中一般要根据目标选择不同的模型来对问题域充分建模。
需求建模常用的模型主要包括了如下:
???需求过程框架概述今天对于需求分析最佳实践,我基本会参考徐锋老师的《软件需求最佳实践》一书进行展开说明,对于该书也推荐给所有准备系统学习需求分析和开发方法的需求人员。
???SERU框架是《软件需求最佳实践》一书中所提倡的一套需求分析方法论,它讲述了一套将目标系统分解为主题域,再分解为流程,最后得到用例以及业务实体的方法,可作为需求分析的指南。
首先对SERU模型的四个字母再做一个说明
??S:Subject Area,表示子问题域,其核心思想是要通过业务来分解系统 ?E:Event,表示业务事件,通过业务事件能够找到流程,通过流程能够找到不同场景和用例。 ?R:Report,表示报表,统一处理查询,分析和统计类需求。 ?U:Use Case,表示用例,需求组织的最小单位,到了需求分析阶段的重要活动和产出。 ?SERU过程框架模型将需求过程分解为了三个阶段,第一个阶段是需求定义,重点是主题域划分和业务事件识别。第二个阶段是理清需求框架和脉络,重点是通过业务流程图转到具体的领域类图和用例图。到了第三个阶段重点就是填充需求细节,包括用例的详细编写,界面和交互设计等。
在SERU框架中,先根据业务相关性以及所涉及组织的职责分区,将目标系统分解成不同的主题域,在这个过程中使用构件图对主题域划分结果建模,不但可以表达出系统的组织结构,还可以表达出不同组织域的协作关系;
在每一个主题域中都包含一些业务事件,通过使用上下文关系图对主题域的范围进行建模,可以得到这些业务事件,从而得到流程;
通过流程分析并使用活动图或跨职能流程图对流程建模,可以清晰地分析出流程中的业务活动及它们之间的关联关系。在对流程分析的过程中同时会发现一些报表,这些报表及流程中的业务活动将会成为用例;
经过流程分析后,流程中的业务活动已非常清晰,剔除那些与目标系统无关的业务活动后,可以将余下的业务活动以及分析得到的报表直接转化成用例,从而得到用例图片段。而在对流程及报表分析过程中,可以提取出目标系统中的所要管理的业务实体,从而得到领域模型片段;
简单总结来说就是整个需求过程框架包括了主题域,上下文,流程,报表,数据,实体六个关键阶段和内容,因此下面我将对上述各个阶段展开做下详细描述。
主题域划分我们看一个传统模块划分的例子,如下。
???在上图的例子中,模块的划分是以“物”为中心的,比如说“文档管理”,这个模块的中心是对“文档”的管理,而系统中文档与公司所有的组织均有关系,这就意味着在调研这部分的需求时,要调研几乎所有的部门才不至于遗漏需求,而需求分析及确认时,则也几乎要与所有部门进行确认,一方面会导致需求分析人员进行需求确认的难度,另一方面也可能会导致需求的遗漏。
另外,如上图例子中,是通过传统的框图来表达系统结构,在这样的框图中,只能表达出系统所包含的模块,却无法表达出模块之间的协作关系。
那么,应该如何对目标系统进行第一层次的分解呢?
为了解决上面的问题,在对目标系统进行分解时应以职责即“事”为线索进行。以职责划分角度出发将目标系统按所要处理的事务分解成不同的块,在SERU框架中将其称为主题域,即Subject。
主题域划分方法与企业职责划分及组织架构吻合度高,用户可以只参与自己有关的主题域的需求调研,只针对与自己有关的主题域需求进行确认,有利于促进用户参与,也有利于保证业务流程的完整性,避免业务流程被人为割裂从而产生需求遗漏。
实际在进行主题域划分时,可以从组织结构以及组织结构中的分管领导作为切入点,将职责相同或有紧密联系的组织放在一起成为职责块,再将职责块所负责的业务域作为独立的主题域。
主题域划分完成后,使用UML规范中的构件图对其建模,构件图不仅能表达出目标系统间的结构:构件,也可以表达出不同部分之间的接口关系:构件之间的接口。
总结一下,主题域划分的要点如下图。
???基于上面的分析我们再来看一个主题域划分的实例。
???见上图,参考案例中体检医院的组织结构中共有六个部门,而这六个部门可以按职责划分三块:销售、生产、后勤,其中销售区块负责体检业务的推销,生产区块则负责体检业务的开展,而后勤区块则负责支持体检医院的日常运行。
有了上面的分析后,就可以按照上面的职责区块将待开发的目标系统划分为三个主题域,分别满足销售区块、生产区块以及后勤区块业务需求。
???销售区块所负责的业务主要是业务推销、客户管理等,需要纳入系统管理的主要是客户服务业务,所以对应的主题域叫做“客户管理子系统”;生产区块主要负责体检业务的开展,所以对应的主题域叫做“体检业务子系统”;而后勤区块包括物资管理及财务管理,因财务管理已经有专用系统,所以需要纳入系统管理的就是物资管理业务,所以对应的主题域叫做“物资管理子系统”。
上图中不但使用构件表达出了主题域及系统的结构,还使用接口表达出了主题域间的接口。
上下文-主题域范围分析主题域划分完成后,对于每个主题域而言,里面究竟包含多少业务流程呢?换句话讲,这个主题域的范围有多大呢?在分析主题域范围时,可以使用上下文关系图来建模,使用一个上下文关系图来表达一个主题域。
在绘制上下文关系图时,将待分析的主题域当作黑盒子,找出所有相关的外部客户(Customer)及内部角色(Worker),再识别出所有外部客户及内部角色主动发起的所有业务事件,根据这些业务事件,按序标出各个角色的反应。
在绘制上下文关系图时,需要注意的是要先识别外部客户主动触发的业务事件,然后再识别内部角色主动触发的业务事件。
???为什么要先识别外部客户主动触发的业务事件呢?因为外部客户所触发的业务事件更可能是业务流程的起点,大部分内部角色所采取的动作大部分是对外部客户所触发业务事件的反应。
绘制上下文关系图是为了识别主题域中的业务事件,所以这个图最好是在和用户进行访谈时就绘制,在纸上绘制的草图就是非常好的方式;若主题域较小、比较简单或是其中的流程非常明显时,可以不需要绘制上下文关系图,不要为了画图而画图。
???参考案例中体检医院的管理系统被分解为三个主题域,其中“体检业务子系统”这个主题域主要的外部客户就是体检者,而内部工作人员包括服务人员、收费人员、体检科室以及综合科医生。
在为这个主题域绘制上下文关系图时,先考虑外部客户主动发起的业务事件,体检者最主要的业务事件就是申请体检,也可能会在体检过程中要求修改,这就是外部客户主动发起的业务事件。
流程分析和识别通过上下文关系图对主题域进行分析后,可以得到主题域中所包含的业务事件,而这些业务事件就是业务流程的起点。
流程分析时,需要注意流程的目标性、内在性、整体性、动态性、层次性、结构性这六大特性,以及流程设计的几大原则,具体可参考流程设计的专业书籍。
流程是需求分析的重要内容,流程图对于和用户确认需求以及向开发团队传递需求都是非常重要的。可以选择使用UML规范中的活动图或商业建模标准中所推荐的跨职能流程图对流程建模。
在绘制流程图时,需要特别注意流程的层次性,在需求分析的早期阶段最好以业务活动作为流程图中的活动,不要过早地进入业务步骤等细节的分析。
???这是SERU框架推荐的主要方法,通过对主题域进行分析并绘制上下文关系图后,即可得到主题域中所包含的业务事件,通过对业务事件所触发的各角色的反应形成业务流程,识别过程如下图所示。
以下是另一个通过业务事件识别流程例子,例子所属的业务领域为手机交易。在这个领域中,可能的业务事件有客户下单,而为了应对这个业务事件,对应的流程就是企业的销售流程。
???除了上面提到的方法外,还可以对目标系统的主要客户以及目标系统的业务生命周期进行研究,从而得到一些业务流程。
拿一个销售管理系统为例,分析客户的生命周期就可以知道存在知道、愿意、购买、接收、付款等阶段,那么对应这些阶段,可能的流程就有市场推广、市场调查、订单管理、配送、收款等流程,具体如下图。
??????报表分析通过流程分析,可以得到流程中的活动,这些活动未来将被转换成为用例。然而,如果只进行流程分析并基于流程中的活动来转换用例,将会遗漏一部分需求,这就是报表类的需求,因为报表类的需求一般不会体现在业务流程中。
报表类的需求是一个广义的概念,包含查询、统计、度量、报表等,主要特征就是它们是数据的消费者,要么是对业务活动的支持,要么是对业务活动的管理,但一般不会出现在业务流程中。
在对高层进行调研时可以得到管理类的报表需求,而在对业务事件进行流程分析时,出于逻辑上的完整也可以识别到支持类的报表需求,如查询,没有这类需求,业务活动会难以进行。
???以参考案例为例,在对高层访谈时,可能会得到这样的信息:希望能定期对体检业务进行统计分析,这就是一个管理类的报表需求:体检业务周期统计报表;
在对体检者申请体检这个业务流程进行分析时,其中有一个业务活动“返还客户”,即客户人员将体检报告返回给体检者,服务人员在返还体检报告时,需要对体检者的体检报告进行查询并确认是否已经返还,这就是一个支持性的报表需求:查询体检报告返还情况。
用例分析在传统的需求分析过程中,用例抽取主要依靠需求分析人员的经验,没有统一的方法及手段,这是目前需求分析中存在主要问题之一。
在SERU框架下,经过将目标系统分解为主题域再分解为流程,流程中清晰地表达了角色所要执行的业务活动,这正是用例的内容,用例即用户使用系统完成业务活动的场景。
除了业务活动可以转换成为用例外,前面所进行的报表类需求也可以比较明显地转换成为用例。
在将业务活动及报表转换为用例后,使用UML中的用例图对用例建模,用例图不但可以表达出用户是如何使用系统的,还可以表达出用户与用户之间的关系,用例与用例之间的关系。
???从流程图转换用例
可以从流程图中转换用例,从流程图转换用例就将流程图中业务活动转换为用例。比如体检者申请体检流程中的业务活动“出具报告”就可以对应转换为一个用例,其执行者是综合科医生,表达的是综合科医生将使用系统为体检者出具体检报告。
???从流程图中转换用例时,先基于流程图分析流程图中的哪一些是不直接使用系统,将其排除,将余下的职能带区(泳道)转为角色,将流程图中的业务活动及判断转换为用例,决定活动是否要转换为用例的标准是它是否属于系统范畴,而决定判断是否要转换为用例的标准是它是否独立。转换过程如下图所示。
???而对于报表类需求,转换为用例的过程是比较明显的,一个具体的报表项可以转换为一个用例。
用例转换实例
???通过体检者申请体检的业务流程转换用例的步骤如下:
确定边界:经过分析,体检者不会直接使用系统,去除其对应的职责带区。其它角色均要直接使用系统,保留。
确定角色:确定4个actor,分别为服务人员、收费人员、体检医生及综合科医生。
确定用例:按照流程图中的职责带区及业务活动及判断进行分析,“服务人员”有两个个业务活动“开单”及“返回客户”,“开单”要在系统中进行记录,“返回客户”要在系统中记录并打印,均属于系统范畴,转换为用例;“收费人员”只有一个业务活动“收费”,“收费”时需要在系统中操作,属于系统范畴,转换为用例;“体检医生”只有一个业务活动“体检并记录结果”,其中体检与系统无关,而记录结果需要在系统中记录,属于系统范畴,转换为用例;“综合科医生”对应一个业务活动“出具报告”及一个判断“体检已完成?”,“出具报告”时需要在系统中记录结果,属于系统范畴,转换为用例,而判断则不是独立的活动,从属于业务活动“出具报告”,不转换为用例。
绘制用例图:用例确定后,可使用rose工具绘制出用例图
业务实体分析通过SERU框架层层分解后,可以得到目标系统的业务流程以及基于业务流程的用例片段,系统的脉络已经清晰。
但正如前面所讲,单一的模型是不充分的,用例模型只是对用户如何使用系统的业务场景进行建模,如果要构建系统,还需要对系统的框架进行建模,即要弄清楚目标系统所要管理的“物”:业务实体,并弄清楚这些业务实体间的关系。
在对业务实体建模时,一般是使用“名词动词法”识别出业务实体。
对业务实体建模选择使用UML规范中的类图或实体图作为模型,类图/实体图中的一个类/实体表达一个业务实体,类/实体的属性用于对业实体的属性建模,而它们之间的关系则可以用来对业务实体间的关联关系建模。
对于比较复杂的业务实体,还可以采用UML规范中的状态图对其建模,可以表达出业务实体的状态切换与触发事件的关系。
同样的,在对业务实体建模时,也需要注意建模的本质:仅是手段,目标是用于理清系统框架及用于沟通,所以不要在模型中加入过多元素及过早考虑细节,不要为了建模而建模。对于业务实体模型来说,实体本身以及业务实体间的关联关系,包括关联关系中的多重性比较重要,而实体属性则相对显得比较细节。
???识别业务实体一般采用“名词动词法”,即将需求描述及分析过程中的名词作为备选类,然后过滤掉与系统无关的或过小的备选类后得到候选类,最后绘成业务实体模型。识别业务实体的过程如下图示意。
???不过,因为使用面向对象思想进行系统分析,业务实体的识别对于需求分析人员来讲相对比较容易,大家可能意识不到这个过程。
还是以上面的体检业务流程来举例,我们进行业务实体分析后形成的业务实体和类图可以通过UML建模做如下呈现。
??????最后-自底向上提炼自底向上的过程包含两方面的内容,一方面是对于用例模型及业务实体模型的组织,另一方面则将各种片段抽象并在抽象过程中消除矛盾。
基于SERU框架分解后,所得到的都是基于流程的用例模型片段以及领域模型片段,这些片段需要组织,组织用例模型、领域模型主要是使用“包”。
???在基于流程分析用例及业务实体时,因为分析的上下文局限于流程范围内,所以不同流程之间的用例及业务实体片段之间可能会存在一些重复、冲突等矛盾。另一方面,即使同一个流程中用例及业务实体,也可能需要向上抽象,从而得到更益于管理及更益于构建的用例模型以及领域模型。