客户真正的需求
我们先来看一幅漫画。相信很多产品经理都应该有看过这幅漫画,漫画的内容讲的是不同的人理解同一个需求都是不一样的,甚至连客户自己描述的需求和他真正想要的都不一样。亨利福特曾经说过一句产品界的名言:如果我当时去问消费者,他们想要什么,那么他们一定会说一匹跑得更快的马。消费者真正想要的是一匹跑得更快的马吗?显然不是,而是想更快更舒适的从A点到B点。很多时候,客户自己是不能完全理解或表达自己真正的需求的,而这正是我们做需求的必要性,挖掘用户背后的真正需求,就成了做需求的基本功。做需求,就好像在玩你画我猜。
如果很幸运,你真正理解了客户想要什么,那么如何真实有效地传达给研发部门,传达给商务和销售呢?或许你看过某些综艺节目,几个人不断地传一个词,传到最后,完全变了样。信息在传递过程中是有失真的,这在商业上是一个很大的损失,也是企业所不允许发生的,所以在软件行业兴起之初,很多巨头就开始研究如何有效的规范化需求的表达。这就有了统一建模语言,英文全称Unified Modeling Language(UML)。所以我们知道了,UML是用来干嘛的了,就是用来有效表达需求的。
统一建模语言概念
大家好好意会一下,统一建模语言,这个名字,不难得出,这是一门语言这个结论。既然是语言,那必定有其词汇、语法以及文章吧。前面也说了,统一建模语言是用来有效表达需求的,和中文、英语、法语亦或计算机语言C++、Java、Python一样,是用来表达的。只不过,中文、英语、法语这些是我们日常表达之用,而计算机语言Java、Python是我们与计算机沟通交流之用,是我们用来给计算机下达指令的语言。而我们的UML是用来跟客户、研发人员或商务、销售表达需求的。所以往往UML会作为软件需求规格说明书的前身。
问什么样的语言最容易理解?那必定是可视化的图形语言,我们日常沟通的语言也大都从图形演变而来,什么楔形文字、象形文字等等。因为人是视觉动物,对于能看见的东西容易记住,也容易下定义,如果你去跟一个古代的人说什么是汽车,那么你一定会崩溃,而如果你跟一个现代的人说什么是汽车,那么他一定觉得你很傻。为什么?因为古代人对汽车完全没有概念,完全没有看过。如果你画了一张汽车的图去跟古代人说,这就是汽车,或许他们真正见到汽车的时候能够知道那叫汽车。所以说,只有图形化的语言是最容易,也是最快速传达真实意思的语言。这也就是为什么UML会采用可视化的图形作为基本的元素。因为这最原始,也最有效。
总而言之,UML是一门用来表达需求的可视化图形语言,有其基本的词汇、语法和文章。词汇就是核心元素,语法就是核心视图,而文章就是我们做需求的产出物需求文档,核心模型。词汇通过一定规则构成了语法,不同的语句组成了一篇篇的文章,同样,元素通过不同的组合方式成为了视图,不同的视图组成了模型。这就是统一建模语言UML。
UML核心元素
UML有八大类元素,分别是边界、参与者(主角)、用例、类、包、组件、节点和关系。每类元素里可能还有子元素,在UML里把子元素叫版型。就像象棋有32子(红黑各16子)一样,通过简单的马走日,象行田,炮隔一,车直线这样的规则,演变出了千变万化的局。而UML就是用这八大元素,通过视图这样的规则,组合出了完整的需求模型。
边界
边界是我们界定事物范围的概念。凭什么你认为那就是汽车,因为你有汽车的判断标准,而那个标准就是边界。边界有很大的主观性。每个人认为的边界都是不一样的。这里有个很有趣的故事,是说当时美国有一部很火的电影,但是也饱受争议,因为它尺度比较大,尺度大,大家都知道什么意思啦,反正你懂的。这件事还闹到了联邦法院,大家整争论的焦点是什么是色情,谁也不能给色情一个很完整的定义,也就是没有判定是色情的标准,全裸的也不一是色情,可能是很高雅的艺术,对吧?所以谁也说服不了谁。最后联邦法院的院长就说了一句很著名的话:I know it when I see it. 什么是色情我不知道,但是不是色情,你拿给我看一下就是知道了这是不是色情。这说明什么?说明法院院长自己内心有一把标尺,能够界定色情的范围,所以法院院长内心有色情的边界,只要进入了这个边界,就认为是色情。所以说边界是我们界定事物范围的概念。
理解边界的概念非常重要,这直接关乎你分析需求的透彻性和完整性。因为我们可以通过不断缩小范围的边界来缩小分析的复杂度。也可以从细处着手,逐步扩大范围的边界来窥得全貌,了解客户真正的需求。就像我们的思维导图一样,可以自顶向下逐步缩小范围,也可以自底向上,逐步扩大范围。我们描述一辆汽车,可以说这是一辆汽车,它由发动机、轮子、外壳和方向盘组成,也可以说发动机、轮子、外壳和方向盘共同组成了汽车。以下是一个边界的例子,大家好好意会一下:
参与者(主角)
我们知道了什么是边界,那么我们就能够界定我们要做的系统的边界,这个边界可以是很粗略很大的概念。我们只需要知道,这个系统有个边界。而参与者就是在系统边界之外,与系统进行交互的人或事物。也就是说参与者在系统边界之外,对系统有明确的期望。参与者还可以是非人,因为系统可以是中间件或半成品,供其他系统调用API。
说到参与者,就不得不说说参与者与统一过程中的涉众、用户、角色这几个概念的关系。涉众是凡是跟系统沾边的人都是涉众,比如开发商、外包商、客户、客户的合作伙伴等等都是涉众,参与者是涉众的一个子集,在需求分析阶段,会从涉众中筛选出参与者。用户是真正使用系统的人,参与者不一定是用户,比如总经理审批业务,但不一定是总经理亲自操作系统,可能是他的助理帮他操作审批。而角色是一组具有相同职责的参与者的集合。角色代表了参与者的职责,参与者代表了涉众的利益,用户代表参与者使用。这就是他们的关系。
参与者有一个版型(子元素)叫业务主角,用在业务建模阶段。要理解这个概念,就必须知道UML里的业务是什么意思。在UML里,业务是指无论有没有系统,都能正常运转的工作。凡是说到业务,就必须抛开系统,去理解现有的业务。所以业务主角就是用来翻译现有业务中参与者的模型。
有业务主角,就有业务配角,在UML里配角叫业务工人。业务工人是系统边界之内,被动参与业务的非参与者。业务工人不是参与者的版型,因为它在系统边界之内。举个例子,机票预订系统中有电话订票的业务,客户通过打电话给呼叫中心,再转接给人工座席,客服再通过Web系统帮客户预定机票。这个过程中,人工座席就是业务工人。
用例
用例是参与者发起的、互相独立的、有结果可供观测的、有意义的活动的集合。简单来说就是一件事情,要完成这件事,需要做一系列的活动,这件事最终有个结果,就叫用例。要完成这件事(用例),可能有不同的实现方式,比如存钱,可以去ATM机存,也可以去柜台存,两种方式的活动步骤是不一样的,这些方式就叫用例实现。
需要注意的是,这里说的用例,全称应该叫“系统用例”,除了系统用例,还用概念用例和业务用例。业务用例固然容易理解,前面有说过,UML里凡是讲业务,都是指没有系统依旧客观存在的现有业务。所以业务用例就是用来翻译现有业务活动的用例。那概念用例呢?可以这么理解,如果直接从现实世界翻译为业务用例之后,由业务用例转为计算机可以理解的系统用例,往往会忽略很多细节,因为业务用例往往边界比较大,而系统用例是计算机能够理解的活动,已经非常细致。要想顺利将业务用例转为细致的计算机可以理解的系统用例,就需要概念用例作为中间过渡。所以说,概念用例是关键业务用例的细化。概念用例不是必须的,如果系统很小,可以完全没有必要做概念建模,但当系统非常庞杂的时候,用概念用例构建概念模型就尤为重要。总而言之,概念用例是关键业务用例的细化,用来过渡到细致的系统用例。
前面讲参与者时有说过,参与者对系统有明确的期望,那这个期望便是用例,系统的功能便是由参与者的期望组成的。一个用例,包括前置条件、实现方式(用例场景)和后置条件(可供观测的结果)构成。所以一个用例,往往是一个动宾短语。
类
熟悉面向对象编程语言的同学可能对这个概念并不陌生。类同样是我们认识世界的抽象概念,例如车是好几种车的抽象类,汽车又是好几中品牌的抽象概念,福特汽车又是好几种类型汽车的抽象概念,什么SUV车型、超跑车型等等。而实例,或者说是对象,就是类的一种具体实现。如张三的一辆福特汽车,张三的汽车是只有一辆的,且完全确定了是什么品牌,什么类型的车,是一个非常具体的概念,可以说,张三的汽车就是一个汽车的实例或叫一个对象。在UML里,有三种类,分别是业务实体,分析类和设计类。其中分析类又包括边界类、控制类和实体类。
业务实体是业务主角执行业务用例时所处理或使用的事物。同样,再次强调一次,再UML里所说的业务是指没有系统,依旧客观存在的现有业务。所以业务实体就是即使没有系统,员工在执行业务任务时,也要使用或处理的事物。例如,要申请公司的一台电脑,那要填写公司资产申请单,这个申请单便是业务实体。
分析类一般用在概念建模阶段。前面有提到概念建模这个概念,是指用细化业务用例的概念用例构建起来的模型。而分析类就是用来描述概念用例是如何实现的,概念用例的实现步骤是怎样的。在概念建模阶段,已经开始引入系统,而业务建模阶段是要抛开系统的概念的。分析类一共有三种:边界类,是现实世界中的计算机窗口、通讯协议、接口等参与者交互的载体;控制类,一个或几个用例的控制行为的建模,主要起到协调对象的作用,如边界类通过控制类访问实体类,或实体类通过控制类访问另一个实体类;实体类,存储信息和相关行为的建模,往往具有永久性,其属性和关系是系统长期需要的,对应往往是数据库的一条记录,实体类可以直接来源于业务实体。
设计类是系统实现中一个或多个对象的抽象,设计类所对应的对象取决于实现的语言。设计类由分析类进一步演化而来,已经非常接近实现代码了。在开发部门,应该说是经常使用的一个元素,开开发设计评审会时,程序员应该提供设计类模型,也就时系统模型。
包、组件、节点
包应该时比较容易理解的,如同文件夹一样,用来将信息分类,形成逻辑单元,主要用于容纳其他元素以达到分类的目的。
组件会相对复杂一点,指的时系统中已存在的,实现了特定功能的,并且符合标准接口规范的,系统可更换部分。组件具有完备性、独立性、逻辑性和透明性。
节点或者设备这两个元素用在系统实施阶段,是指至少带有一个CUP、内存以及可能带有其他设备的处理单元。一般服务器、工作站、客户端就是一个节点。一般情况下,画部署视图,人们会用更加形象的图形来说明,而不是使用UML里定义的节点或设备来画视图,如Visio里就提供了服务器、路由器等等非常具体、现实的图册以供绘画部署视图。所以这两个元素也是最不常用的。
关系
UML里有错综复杂的关系,正是由这些关系构成了元素组合成视图的规则。一共有9种关系,分别是关联、依赖、扩展、包含、精化、实现、泛化、聚合、组合。
*有些图形不是很标准,但基本就是这个样子
UML核心视图
视图是UML的语法、语句。由核心元素通过一定的规则组成视图。包括静态视图和动态视图。其中静态视图往往用来描述元素的关系,动态视图往往用来描述实现过程。静态视图包括用例图、类图和包图,或许还包括系统架构图。动态视图是我们最常看到的,包括活动图、状态图、时序图和协作图。
静态视图:用例图
用例图包括业务用例图、业务用来实现图,系统用例图和系统用例实现图,准确的说,应该还包括概念用例图。业务用例图用来翻译现实世界中现有的业务,业务用来实现图用来描述业务用例的实现方法,系统用例基本上就是系统的功能了,描述系统要完成的事,系统用例实现图用来描述系统用例的实现方式,如查看日志,我可以从顶部导航栏的日志小图标点进去查看,业务可以从系统管理里的日志管理里进入查看。概念用例图是用概念用例绘画的图,是细化关键业务用例的用例图。以下是一个用例图的例子,大家好好意会一下:
静态视图:类图
类图是用例描述元素的数量关系的图形。在业务层,有业务层类图,是用来描述业务实体数量关系的图形。在概念层,有概念层类图,是用分析类中的实体类,描述实体类的数量关系的图形。在实现层,有实现层类图,是使用了具体实现语言后,构建的Bean图。
静态视图:包图
所谓包图就是指我们需求文档构成的逻辑图,或者说是系统构成的逻辑图,如采用MVC架构下的Business层,BusinessControl层和View层。包图可以分为两种领域包图和层次包图。
动态视图:活动图
用例表达了参与者的一个期望或目标,而活动图表达了如何实现这个目标。大家再回忆一下用例的概念,用例是活动的集合。那这些活动是怎样的一个顺序,又由谁来执行?如何表达这些信息呢?在UML里就是用活动图来表达。我们可以通过活动图来构建业务场景模型或用例场景模型。活动图包括以下几点内容:
活动:执行单元(入口/执行/退出)
判断:根据某个条件决策
同步:同步起初/结束,并行执行
结束点:标记业务的终止
基本流:从开始到结束的流程
支流:带条件触发的流程
异常流:非正常的业务流分支
组合活动:活动嵌套子活动
单纯看上图,我们只是知道了活动的执行顺序,但我们无法知道每个活动是谁执行的。以活动执行者为泳道重构图形,我们就得到了带泳道的对象交互图或者是带角色职责的活动图。
动态视图:状态图
状态图是用来对某一元素的动态行为状态构建的模型图。状态图通常用来描述一个对象的行为。前面我们在讲解类的概念时,有提到,对象就是一个类的实例,如张三的福特汽车,是一个非常具体的事物,所以这是一个对象。这个汽车对象可以有熄火、启动中、行驶中、刹车中等等状态,把每个状态的实现顺序构建一个模型图形,那就是状态图。状态图包括以下内容:
状态:执行活动或等事件时条件
复合状态:状态中嵌套子状态
转移:两个状态之间的关系
事件:特定动作或行为
条件:布尔表达式
最终状态:状态机结束
动态视图:时序图
时序图用来描述按时间顺序排列的对象交互过程。时序图描述了在参与交互的对象中所发生的事,以及这些对象通过互相发送消息进行通信。在绘制时序图前,应该已经画好了相关用例的实现过程活动图。简而言之,时序图是表达了用例是如何使用或产生对象来实现的。而活动图是表达用例是如何一步一步实现的。再次解释一下对象的概念,就是类的实例,时序图里的对象可以是业务实体对象,也可以是分析类的实体类对象,或者是设计类的设计类对象。对应的就有用业务实体对象画的业务模型时序图,用分析类的实体类对象画的概念模型时序图和用设计类对象画的设计模型时序图。时序图的内容包括:
对象:参与交互的对象
生命周期线:表示对象存在,激活时出现会话
消息:新建会话或延续会话
会话:表示一次交互
销毁:表示对象生命周期终止
1、业务模型时序图
业务模型时序图是用业务实体对象绘画的,目的是表达业务用例是如何通过使用或产生业务实体对象来实现的。
2、概念模型时序图
概念模型时序图是用分析类的实体类对象绘画的,目标同样是表达业务用例是如何通过使用或产生业务实体对象来实现的。所不同的是,用分析类的实体类对象绘画的时序图已经带有计算机实现的理解。
3、设计模型时序图
设计模型时序图是用设计类对象绘制的。目的是实现概念模型中某个关键的事件流,一般以一个完整的交互过程为单位,消息细致到方法的级别。
动态视图:协作图
协作图与时序图本质上是一样的,目的都是描述对象间的交互过程。所不同的是协作图展示了对象间的关系,更适合用于获的对对象结构的理解,而时序图,则更适合用于获得对象调用过程的理解。所以协作图同样可以用业务实体对象、分析类的实体类对象和设计类对象绘画,也同样有三种类型的协作图:业务模型协作图,概念模型协作图和设计模型协作图。不过,协作图有时候不需要完整的场景,只需要将关键的消息绘制出来即可,因为协作图更在意的是对象的结构及其互相的影响。协作图的内容如下:
对象:参与协作的对象
对象关联:两个对象的临时关联
消息:新建会话或延续会话
1、业务模型协作图
用业务实体对象绘制的,用来描述业务用例场景中对象的结构关系和关键消息的对象模型。
2、概念模型协作图
用分析类的实体类对象绘制的,用来描述概念用例场景中对象的结构关系和关键消息的对象模型。
3、设计模型协作图
用设计类对象绘制的,用来描述系统用例场景中对象的结构关系和关键消息的对象模型。一般会以一个完整交互为单位,消息细致到方法的级别。
UML核心模型
如果说元素是词汇,视图是语法,那么由许许多多的视图按业务层面、概念层面或设计层面这样逻辑划分组合起来的就是模型,也就是由不同语句,按不同的段落划分组合起来的文章,或者简单得说,这就是我们的需求文档。UML的核心模型包括用例模型、领域模型、分析模型、设计模型和实施模型。
用例模型
用例是贯穿整个系统开发的主线。用例模型是需求工作流程的结果,可以作为设计工作流程和测试工作流程到输入。用例模型分为三种,分别是翻译现有业务的业务用例模型,细化业务用例的概念用例模型,以及构建系统的系统用例模型。
1、业务用例模型
业务用例模型是翻译现有业务的需求文档。是在系统规划的先启阶段中完成。我们一般理解的需求是系统的需求,也就是需求规格说明书中描述的内容,但其实要想真正理解系统的需求,就必须理解现有业务的模型。业务用例模型讲述的业务的范围,系统用例模型描述的系统的范围。所以建立用例模型是不能带有计算机设计的考虑。一个完整的业务用例模型包括以下内容:
业务用例视图:业务主角、业务用例
业务用例场景:说明业务用例的实现过程
业务用例规约:对业务用例编写规则
业务规则:执行需遵守的规范、惯例等
业务对象模型:描述关键的业务对象
业务用例实现图:业务用例的实现关系
包图:按模块或主角分包组织业务用例
2、概念用例模型
概念用例模型是业务用例模型的一个子集,是用来“分解”较大的业务用例,从中找到关键的、核心的工作单元。概念用例模型得到的是“缩小”了粒度的用例,方便我们将业务用例过渡到系统用例。概念用例可以通过包含、泛化、扩展关系连接到基本的业务用例。完整的概念用例模型的主要内容包括:
概念用例视图:概念用例与基本用例及其关系
概念用例分析:业务用例模型中重要的用例场景或部分场景
分析类视图:分析类的关系
分析场景:分析类绘制的对象交互图
3、系统用例模型
系统用例就是我们常说说的需求,通常就已经是系统的功能。系统用例也可以简称为用例,所以系统用例模型,也就是常说的用例模型。系统用例模型就是需求工作的最终结果。可以作为系统设计工作和测试工作的输入。完整的系统用例模型的内容包括:
业务用例:系统用例精化业务用例
概念用例:业务用例到系统用例的过度
用例视图:包括参与者和用例
用例规约:用例的执行事件流和规则
补充规约:描述用例相关的非功能性需求
业务规则:必须遵守的规范或惯例
用例实现:用例的实现方式
用例场景:参与者与计算机交互的过程
分析对象:计算机逻辑的概念化产物
领域模型
领域模型是采用业务实体对象建立起来的模型。领域模型中使用到的业务实体对象就成为领域类。在现实世界中,业务是由一系列的业务实体对象相互交互而完成的,领域模型就是试图挖掘其中的关系。一般使用业务层类图描述。
分析模型
分析模型用分析类构建系统原型,是从需求到设计模型的过渡。分析模型采用MVC架构,将用例场景中描述的业务分解为边界(操作界面或展示界面)、控制类(业务逻辑)、实体(数据)。
设计模型
设计模型是用设计类绘制的,描述用例实现的对象模型。是编码实现前的最后一道工作。
组件模型
组件是特殊的包,用于容纳分析类和设计类。组件建模的重要工作就是根据要实现的一组功能建立组件。一般分布式系统、支持第三方服务、采用架构开发、在系统或子系统中大量复用单元的需要构建组件模型。
实施模型
实施模型由配置节点和组件构成。实施模型一般在分布式系统中使用,可以描述硬件设备的配置、通信以及各硬件设备上的各种组件和对象配置。往往实施模型会使用其他更加形象图形代替,所以UML里的实施模型往往不常用。
统一过程
通过上面的了解,我们知道了UML的元素、视图以及各种各样的模型。在介绍模型的时候也在不断提到,所使用的阶段。那这个阶段是指什么阶段呢?谈到统一建模语言UML就不得不提到统一过程。统一过程归纳和集成了软件开发活动中的最佳实践,它定义了软件开发过程中最重要的四个阶段和九个核心工作流,定义了参与软件开发过程的各种角色以及他们的职责,还定义了软件生产过程中的工件,并提供了模板。最后采用演进式软件生命周期(迭代)将工作、角色和工件串在一起,形成统一过程。
前面一直提到的业务建模阶段、概念建模阶段或者系统建模阶段,这些概念就是来源于统一过程。UML是一个表达的工具,在什么阶段说什么话,就成为了UML的职责。而这些阶段从哪里定义?就是从统一过程中定义。如业务建模阶段用业务用例模型表达。需求建模阶段用系统用例模型表达。所以结合着统一过程,我们就能明白UML是如何在软件研发过程中发挥作用的。
业务建模工作流程
在统一过程中的业务建模阶段,是使用UML语言中的业务用例、业务实体、业务用例模型图来翻译现有的业务模型。如果客户的业务领域已经非常成熟,那么只需要翻译现有业务,如果客户想要改进业务流程,那么需要与客户一起完成业务的建模,如果客户是想改革现有的业务模式,也同样需要与客户一起建立业务模型。如果业务模型大部分已经成熟了,或已经有较成型的系统了,则只需要构建领域模型。下图是业务建模的工作流程和参与人员及其产出物。
系统建模工作流程
系统建模通常就是指需求了,主要使用系统用例模型来构建。下图是系统建模的工作流程和参与人员及其产出物。
分析设计建模工作流程
我们常说的开发设计评审里,评审的内容就是分析设计建立的模型,即概要设计和详细设计。主要使用分析模型和设计模型来完成设计过程。
实施建模工作流程
实施建模的目的是建立组件及其所在的实施子系统的集合。是实施人员实施系统前的分析模型。
结束语
UML是一个有效表达需求的工具,而工具是使用在特定场景当中的,统一过程便是UML的用武之地。UML只有结合统一过程才能真正将其零散的元素、视图和模型贯穿起来,发挥其真正的力量。然而统一过程又是一个很大的话题。
*注:本文观点和附图来自《大象-Thinking in UML》