UML程序设计实例—电梯调度模拟器—本章通过电梯调度模拟器的例子详细介绍了如何利用UML进行一个实际系统的开发。
这个系统的实现过程,遵循Rational统一软件开发过程,最后用Vc++编码实现。
问题描述在开发任何一个系统之前,开发人员对所要开发的系统的初步理解首先是从用户的问题描述开始的。
问题描述的内容包括系统的基本功能需求,用户对系统的性能,外观等特性的要求。
这种描述根据开发项目的规模不同,呈现不同的形式。
对于大的项目,问题描述可能是长达几页(几十页)的需求规格说明;对于小的项目,可能只是口头上的几句陈述。
通过问题描述,开发人员对要开发的系统产生一个大概的印象。
此实例的问题描述如下:有一座8层楼房,每层提供一组按钮(“上”或“下”),用于请求电梯的到达;每部电梯内部提供一个控制面板,提供用户对目标楼层的选择,并显示电梯当前所处楼层、运行方向。
两部电梯由一个调度器统一调度。
如果没有请求,并超过一定时限,电梯回到一楼。
希望开发人员能实现一个电梯调度模拟器来模拟如上所述的一切,对电梯的调度准则没有做特别要求。
此外,用户还可能会对系统的性能,外观等特性提出要求,这些都需要在开发过程中加以考虑。
需求分析拟订侯选需求在系统开发启动之前,首先要对项目做一些可行性分析。
在Rational统一软件开发过程中,称这个阶段为初始阶段。
在初始阶段主要是跟各方进行交流,广泛收集信息,听取客户和专家的建议。
并对这些信息和建议进行记录,整理得到一个后选需求列表。
后选需求列表中应包括如下各项1.名称2.简要说明3.状态(建议的、批准的、并入的或证实的)4.实现成本估算(人小时,人月)5.优先级(关键的、重要的或辅助的)6.实现风险的级别(关键的、重要的或一般的)表1 后选需求列表这时对系统所要实现的功能在整体上有了一个大致的了解。
然后明确哪一部分功能是系统中应该实现的,哪一部分功能是由其它外部系统实现的。
即确定出系统的功能范围,并粗略估计一下项目的花费和可能得到的收益。
这个阶段最重要的是弄清楚启动这个项目是不是有意义,有价值。
初始阶段根据项目的大小,表现为不同的形式。
对于小的项目,可能只需要与相关人员进行一些交流和讨论。
而对于大的项目可能要花费几个月的时间进行可行性分析。
经过分析,作出启动项目的决定之后,就进入开发过程的细化阶段。
理解系统上下文建立领域模型如果对要实现系统所要解决的问题领域没有一个清楚的了解,就不可能开发出一个满足用户需求的软件。
因此,进行系统建模时,应首先建立领域模型,描述问题领域中的基本概念。
建立领域模型时,先不要考虑软件是怎样实现的,而只关心如何将用户和领域专家头脑中与业务过程相关的概念组织起来,并将业务过程描绘出来。
所以在电梯调度模拟器这个实例中,暂不考虑用户界面,而首先考虑把电梯的运做过程描述清楚。
用户界面的加入推迟到分析阶段的后期进行。
首先从问题描述和所了解的领域知识中抽取出可能与解决问题有关的重要概念(领域对象)。
本例中通过分析问题描述提取出了这样一些名词(概念)。
同时,为了便于理解,各名词的修饰语也被一同标注出来。
1.楼房2.(两部)电梯3.(每层)一组按钮(“上”或“下”)4.(电梯内部)控制面板5.用户6.调度器接下来,再抽取问题描述中重要动词短语,它们可能会成为某个类的属性或方法。
1.请求电梯的到达;2.提供用户对目标楼层的选择;3.显示电梯当前所处楼层、运行方向通过对这些概念做进一步分析,不难发现2.电梯、3.按钮(“上”或“下”)、4.控制面板、5.用户、9.调度器等这些概念在电梯运做过程中都担当一定的职责,可以把它们抽象为系统中的一个类。
“请求电梯的到达”可以作为外部控制面板的职责;“提供用户对目标楼层的选择”作为内部控制面板的职责;“显示电梯当前所处楼层、运行方向”作为电梯的职责。
此外,还有1.楼房,它在电梯运做过程中不与任何其它对象交互,也不承担任何职责,也不能成为任何其它对象的属性或方法,则把它删除。
根据以上分析,初步地找出了系统中的一些类实体,再根据用户或领域专家对电梯运做过程的描述,以及开发者本人对问题的理解,建立起这些对象之间的关联关系。
此外,根据问题描述中限定这些概念的量词(例如:8层、两部、一个等),还可以进一步描述它们之间的多重性关系。
然后,为每个类分配职责,并添加一些必要的注释信息。
这样就建立起了这个系统的原始领域模型,如图1所示。
图1 电梯运行系统领域模型建立业务模型至此,通过领域模型描述了问题领域中存在的重要概念,并从静态视角描述了它们之间的关系。
考察系统的动态行为是正确理解一个系统运做情况的关键。
所以还需要刻画出系统的动态特性。
这一点通过建立系统的业务模型来实现。
在这个实例中,主要通过活动图和交互图来描述电梯使用的内部运做过程。
根据对问题的理解,建立下面的活动图来描述乘客使用电梯过程中发生的各个活动。
图2 电梯运作之活动图为了进一步描述领域对象之间的交互关系,建立下面的顺序图描述电梯运作系统中各对象间的信息传递。
图3 电梯运作之顺序图建立词汇表在建立领域模型和业务模型的同时,收集问题领域中的一些重要概念,建立起一个可供用户,项目经理、系统分析员、开发人员、测试人员和其他相关人员共同使用的词汇表。
这样各种人员就可以使用共同的术语来进行讨论和交流,不仅为系统的实现带来很多便利,还可以防止因误解而使开发的系统偏离用户的真正需求。
提取用例建立用例模型对系统运作过程有了一定了解之后,下一步开始考虑系统的功能。
通过分析业务模型找出执行者并提取用例,建立用例模型来描述系统应实现的功能。
首先,通过分析业务模型找出系统的潜在用户,即执行者。
在本实例中只有一类执行者——电梯乘客。
然后,通过跟踪执行者与系统的交互行为,找出用例。
在本实例中,用户与系统有两次交互,一次是按上/下按钮,请求电梯到达,另一次是进入电梯后,通过内部控制面板选择目标楼层。
进一步分析,会发现用户与电梯的这两次交互都需要对电梯进行调度。
因此提取出公共用例“调度电梯”。
用例图如图4。
图4 用例图简单描述用例提取出用例以后,应对每一个用例做一个简单描述。
以表明它的功能和大致的执行流程。
这个描述,在Uml_Designer中,可以通过添加注释体来实现,也可以写入用例的规格说明中。
例如,对调度电梯这个用例所做的简单描述:调度电梯过程:有两个触发条件:➢用户有请求(包括请求电梯到达和选择目标楼层);➢某个时钟信号到达第一种情况:1.获取用户请求;2.获取电梯的当前状态;3.调度器调度,调度结果通知电梯;4.电梯运动。
第二种情况:1.分析时钟信号;2.获取电梯当前状态;3.调度器调度,调度结果通知电梯;4.电梯执行调度结果。
确定用例优先级别对于大的系统,会找到好多用例。
但这些用例对所开发的系统来说,并不同等重要。
所以确定用例的优先级别是很必要的,对于高优先级的用例,首先对它进行分析,设计,甚至实现;而对于低优先级的用例可以留到后面迭带过程中再予以考虑。
那些优先级别较高的用例就刻画出了系统的体系结构。
本实例由于规模较小,所以没有实施这一过程。
但这一过程在系统实现过程中,是有着重要意义的。
细化用例在这一阶段,用例分析员应与用户密切合作,商讨完成。
首先描述用例执行过程的基本路径,然后再描述发生异常时可能会出现的分支路径。
对有的用例来说,文本描述就足够了。
但对于对象间交互比较复杂的用例,借助顺序图、合作图和活动图来描述,则更能说明问题,更易于交流。
当然,若能采用图文并貌的方法,则更好不过了。
下面的活动图描述了调度电梯用例的一种场景。
图5 调度电梯之活动图设计用例界面现在对业务执行过程有了清楚的认识,下一步加入系统界面。
首先分析用例在与用户进行交互时,需要用户提供什么信息,系统应向用户返回什么信息。
设计的界面应能帮助用户和系统完成这种交互。
加入系统界面后,作为电梯模拟器系统,它的用例才被完整的进行了考虑。
在电梯运行模拟过程中,需要用户输入电梯到达请求和对目标楼层的选择,系统要向用户显示电梯运行的模拟情况,比如电梯的当前状态信息等。
所以界面中应能提供控件来显示这些行为和状态。
在用例模型中增加一个新的用例:系统界面,执行者相应改为模拟器用户。
结构化用例模型结构化用例模型是指通过进一步分析,提取那些公用的模块和那些可选的分支模块,使它们单独各自成为一个用例。
然后,标出用例间的使用和扩展关系。
用例图调整后如下图。
图6 用例图分析在需求分析阶段所做的各项工作,都是面向问题领域的。
是为了充分的理解所要解决的问题空间,以及与各方进行交流和讨论。
采用的术语也都是客户容易理解的。
进入分析阶段之后,所做的工作开始转向面向实现领域,主要是为了帮助开发者更深入的理解系统的实现。
所采用的术语也逐渐转向面向便于程序代码的实现。
在分析阶段,所建立的模型仍然是概念层次上的。
虽然是深入系统内部进行分析,但分析阶段并不考虑系统最终实现时的一些特性,比如:实现语言、操作平台,可用构件,用户界面技术、数据库技术等等。
这些是设计和实现阶段所要解决的问题。
识别分析类通过分析用例图和用例描述,找出分析类。
这些分析类在用例的实现过程中,承担一种或几种职责。
它们相互合作共同实现用例描述的功能。
这些分析类有一部分可以从问题域中的相关实体直接对应得到,而其它大多数则需要通过分析抽象得到。
分析类一般可以分为三种:边界类、实体类和控制类。
边界类用于系统与角色之间的交互,系统通过边界类向执行者请求信息,返回和显示信息(如用户界面)。
在此实例中,可以抽象出一个SystemInterface类,作为用户与系统交互的界面。
通过这个界面,用户可以初始化模拟器、启动模拟和终止模拟器运行。
此外,通过此界面用户还可以实现与内部控制面板和外部控制面板的交互。
实体类用于为系统长期存在的信息建模。
通常情况下,实体类可由问题域中的实体直接对应得到。
此实例中如电梯,内、外部控制面板。
控制类是在一个用例实现过程中协调其它对象的交互,并控制实现流程的一类对象。
它们在用例的实现过程中,承担了管理和控制的职责。
本例中,Dispatcher担当了这样一个角色。
此外,为了防止Dispatcher负担过大,引入一个CentralManager类来负责Dispather 与其它对象的交互,比如信息的获取,调度命令的下达等;而Dispather则专门负责电梯调度算法的实现。
分析类如图7所示。
图7 分析类图接着,建立如下图所示的顺序图,进一步描述这些类的实例间的交互协作关系和信息传递。
图8 电梯使用过程识别各个类的职责一个类可能在多个用例中担当(同种和不同种)角色:比如,SytemInterface类参与了系统界面、请求电梯到达和选择目标楼层三个用例。
一个类的职责是它在不同用例实现中所起作用的总和。