Rose与软件工程

来源:互联网 发布:synchronized java 编辑:程序博客网 时间:2024/06/07 06:28

在面向对象无孔不入的今天,利用对象的思想为软件系统建模,已经成为软件开发的主要工作,而传统的编码工作却“退居二线”了。一个系统的模型建的好,就为满足用户需求、保证系统的稳定性和质量、提高系统的扩展性打下了良好的基础。今天我为大家介绍一个面向对象建模的语言和工具,这就是UML和Rational ROSE。

UML,Unified Modeling Language,统一建模语言,是一种面向对象的建模语言,它的主要作用是帮助我们对软件系统进行面向对象的描述和建模,它可以描述这个软件开发过程从需求分析直到实现和测试的全过程。UML通过建立各种类、类之间的关联、类/对象怎样相互配合实现系统的动态行为等成分(这些都称为模型元素)来组建整个模型,刻画客观世界。UML提供了各种图形,比如Use Case图、类图、顺序图、协作图、状态图等,来把这些模型元素及其关系可视化,让人们可以清楚容易的理解模型。我们可以从多个视角来考察模型,从而更加全面的了解模型,这样同一个模型元素可能会出现在多个图中,对应多个图形元素。

ROSE是美国Rational公司的面向对象建模工具,利用这个工具,我们可以建立用UML描述的软件系统的模型,而且可以自动生成和维护C++、Java、VB、Oracle等语言和系统的代码。

ROSE的界面分为三个部分——Browser窗口、Diagram窗口和Document窗口。Browser窗口用来浏览、创建、删除和修改模型中的模型元素;Diagram窗口用来显示和创作模型的各种图;而Document窗口则是用来显示和书写各个模型元素的文档注释。

如果你想要建造一个软件系统,首先必须先搞清楚用户需求,也就是你的软件系统的功能是什么。这是一切开发的基础。有了需求,接下来的工作就是分析系统的静态结构,看看要实现这些功能,我们的系统中必须要由哪些东西。系统的大体结构定下来之后,就要看这些系统成分是怎样相互配合实现系统功能(即系统的动态结构)的,同时还必须考虑与实现环境有关的细节,比如用什么语言啦,在什么操作系统上转啦,等等,这个工作,就是设计。设计工作细化到一定程度,就可以编码实现了。而最后的工作,毫无疑问,就是测试和维护。总之,这个顺序大体上就是“功能——静态结构——动态结构——编码——测试——维护”。

我们通过一个简单的例子来浏览一下UML这种语言在软件系统建造的全过程中所起的作用,并初步了解一下ROSE的用法。

需求,功能

好的,首先是用户需求,系统功能。

我们的例子其实很简单,它是一个ToDo(待办事宜)表的维护工具,可以为用户创建、删除和管理ToDo信息。ToDo表的信息存贮在文件系统中。
OK,对于这样一个需求,应该怎样用UML来描述呢?
首先,我们需要识别系统的用户和相关的外部系统,在UML中,它们被称为Actor(角色)。识别Actor是很重要的,它可以帮助我们界定软件系统的边界,引导我们发掘用户的需求,辅助我们设计用户界面等等,是需求分析阶段的第一步。对于我们这个简单例子,有两个Actor:ToDo User(系统的用户) 和 FileSystem(相关外部系统)。
接下来,针对每个Actor,我们开始分析系统的Use Case。Use Case是一个UML中非常重要的概念,在使用UML的整个软件开发过程中,Use Case处于一个中心地位。
那么,到底什么是Use Case呢?在UML的文档中,Use Case的定义是:在不展现一个系统或子系统内部结构的情况下,对系统或子系统的某个连贯的功能单元的定义和描述。有点拗口,对吧?其实Use Case就是对系统功能的描述而已,不过一个Use Case描述的是整个系统功能的一部分,这一部分一定要是在逻辑上相对完整的功能流程。
(唔?Use Case也没什么特别的嘛!怎么这玩意儿会在开发中处于一个中心地位呢?)在使用UML的开发过程中,需求是用Use Case来表达的,界面是在Use Case的辅助下设计的,很多类是根据Use Case来发现的,测试实例是根据Use Case来生成的,包括整个开发的管理和任务分配,也是依据Use Case来组织的。啊,Use Case,简直太重要了!好了,Use Case就吹到这儿,具体的使用还要在实践中去体会,“运用之妙,存乎一心”也!
对于每个Actor来说,他都要使用系统的某项功能,所以我们识别和分析Use Case是,要对于每个Actor来逐个进行。对于ToDo User,我们可以轻易的识别出两个Use Case:Add Task 和 Remove Task。ToDo User主动使用这两个Use Case所描述的系统功能,所以在我们的Use Case图上,ToDo User和这两个Use Case的关系是用从ToDo User发出的箭头来表示的。对于FileSystem,我们识别出的也是同样的两个Use Case,不过这次箭头从Use Case指向FileSystem,表示FileSystem是被动的。

Use Case图


Use Case可以用很多方式来描述,我们可以用自然语言(英语,汉语,随您的便),可以用形式化语言(哇!太酷了吧!),也可以用各种图示。在UML中,通常用两种图来描述Use Case,它们就是顺序图(Sequence Diagram)和协作图(Collaboration Diagram)。

交互图:顺序图和协作图

从面向对象的角度来看,系统的功能是由一组对象通过相互发送消息来完成的,顺序图和协作图就是通过描述这样的对象和消息来描述系统的动态行为的。我们先用一个顺序图来描述Use Case AddTask。

AddTask的功能是向ToDo表中加入一个Task项,它的步骤应该是:

  1. 打开加入Task项的窗口;
  2. 输入相应信息;
  3. 生成一个Task对象;
  4. 把这个Task加入到Task表中。

那么,我们的顺序图就可以画成:

顺序图

图中,方块表示一个对象,方块中的文字中冒号之前的部分是对象的名字,冒号之后的是对象所属的类的名字。方块下面的竖直虚线是对象的生命线,表示对象按照从上到下的时间轴的在某段时间内存在。对象间的箭头表示对象之间的消息通讯。而那些狭长的长方块表示某个操作方法执行的时间和调用关系。

顺序图有一个孪生兄弟——协作图,AddTask的协作图是这样的。

协作图

这两种图描述的其实是同一种东西,即实现某种系统功能的一组对象和它们之间的消息传递。不过在顺序图中,时间是作为一个显式的因素出现的,这是的顺序图在构造实时系统时特别有用。而在协作图中,没有显式的时间因素,但是对象之间的关联是一目了然的,这对我们在一组相互关联的对象的语境中考察它们的消息传递是很有帮助的。顺序图和协作图是对同一事物的不同角度的考察。

我们从Use Case自然语言的描述得到了它的顺序图,从顺序图中我们可以发现许多类。你瞧,我们有一个窗口,所以需要有一个对应的窗口类;我们有一个Task对象,相应的就得有一个Task类,类似的,Tasks这个用来管理和组织Task的集合对象也是必须的。Great!现在你看到Use Case和顺序图对识别和发现类的作用了吧!在传统的面向对象分析中,类的识别是靠分析人员的经验和灵感来进行的,这太难以把握了。现在有了Use Case的概念,就可以为对象和类的识别提供一个有力的线索和支点。通过分析Use Case,构造它的顺序图描述,再加上传统的对问题域中的对象和类的考察,可以发现大多数和系统相关的类。面向对象分析中最重要也是最困难的识别和分析类的工作再也不是一种神秘的法术了(你凌空一指,变出了类),现在人人都可以胜任这个活儿了。

经过识别和分析Use Case,我们的需求分析工作可以告一段落了。现在我们着手分析系统的静态结构——就是类的分析和设计。

静态结构分析

通过分析Use Case和问题域,我们得到了类。现在我们要分析这些类的属性、操作和它们之间的关系,即系统的静态结构。

关于类的属性和操作的识别和分析,众多的面向对象分析的书籍中已经有较多的论述,我不多说了。属性就是对象必须要存贮的信息,而类的操作,则可以通过顺序图中向对象发送的消息来识别。我们重点看一看类之间的关联。

系统的静态结构主要用类图来表示。在类图中,类用一个方框来表示,这个方框用横线分为三个部分,第一部分是类的名字,第二部分是类的属性,第三部分是类的操作。类之间的关联用一条连接类方框的横线来表示。一端有箭头的的横线表示单向关联,没有箭头的表示双向关联。对类之间关联的良好分析对以后的实现和扩充都有非常大的帮助。

逻辑上相关的类可以被封装成包,这为我们组织和管理所开发的系统以及开发过程提供了一个很好的手段。大家在我们这个例子的类图上可以看到几个包。

在这里,需要解释一下所谓的“三层”结构模型:用户界面层、事务规则层和数据层。三层结构是对客户/服务器结构的扩展,在客户/服务器模型把用户界面和数据存贮与处理分离的基础上,三层结构把事务规则独立成为一层。为什么呢?大家知道,在一个系统中,最容易发生变化的是系统的界面,其次是系统的处理逻辑、规则和功能,最稳定的是系统中的数据。如果我们把处理逻辑放在客户端,那么对处理逻辑的任何一点修改都要对每个客户进行修改;反过来,对用户界面的改动也可能会影响到处理逻辑。如果我们把处理逻辑放在服务器一端呢?势必会影响到数据的稳定性。所以,把处理逻辑单独分为一层,可以使系统的结构更加清晰、可扩展性、稳定性更强,为以后的扩充和维护带来了极大的好处。现在很多公司都出品自己的专门用于中间的事务规则层的所谓“应用服务器”,包括NetScape的Application Server、Microsoft的Transaction Server等等。随着Internet和WWW的发展和“瘦客户”的流行,用户界面逐渐向浏览器上靠拢,而应用服务器和Web服务器的结合也日渐紧密,这些发展对进一步降低成本,增强系统的扩充性、可配置性、可管理性等等都起到了很大作用。

面向对象软件工程的一个很大的好处就是在分析和设计之间没有什么明显的区别,更不会有传统软件工程中在分析和设计之间的语义上的鸿沟。在分析进行到一定程度时,把具体实现环境的因素考虑进来,就自然过渡到了设计阶段。由于我们的小例子使用文件系统存贮ToDo表的信息,所以我们需要一个CFile类来封装文件系统的功能和操作。

类图

至此,我们的小例子的静态结构分析和设计已经有了初步的成果。接下来,可以根据这些成果分析和设计系统的动态结构。这包括细化和修改Use Case的描述,比如把类的操作和对象之间的消息相对应、充填参数等等,还有为比较复杂的类设计状态图等工作。因为这个例子比较简单,没有什么比较复杂的类,所以没有必要设计状态图,只需要细化一下Use Case的顺序图就可以了。

这些分析和设计的工作经常是相互影响和促进的。你常常会在分析动态结构的时候,发现漏掉了一个类、一个属性,或者需要加上一个操作;而随着对静态结构的进一步深入刻画,对类之间的关联、消息传递的设计也会不断发生变化。所以我们要不断的对设计方案进行深化和细化,直到达到一个稳定的状态,这时我们就可以考虑系统的实现了。

实现模型

在逻辑模型建立之后,我们可以建立实现模型。

在实现模型中,我们定义一些组成软件系统的部件,比如DLL库啦,EXE文件啦,Java Applet啦,ActiveX Control啦,Web页面啦等等。定义这些部件和它们之间的关系,对代码的自动生成、软件系统的配置、测试管理、软件的打包发行等等都有很大的好处。

对于我们这个小例子,只有一个部件——最终的EXE文件ToDoList。

在ROSE中的Component View包中,我们创建这个部件。然后可以将各个类拖动到这个部件上,这表示这些类最终是用这个部件实现的。

做完了所有这些活,我们就可以自动生成代码了!ROSE可以自动生成C++、Java、CORBA IDL、Visual Basic、Visual C++、Oracle Schema等等不同语言和系统的代码,并且可以进行“双向工程”——模型和代码之间的双向转换,大大减轻了代码书写的工作。可是代码生成内容很多,已经不是我们这个简单的教程所能包容的了。只有等以后有时间在作个专题吧。很期待吧?呵呵,那就请你多支持我喽!

原创粉丝点击