UML参考手册
第一部分 背景知识
第2章 模型的性质与目标
本章将解释什么是模型,模型有何用途以及如何使用模型。本章还将解释模型的不同层次:理想的,部分的和基于工具的。
2.1 什么是模型
模型是用某种工具对同类或其他工具的表达方式。模型从某一个建模观点出发,抓住事物最重要的方面而简化或忽略其他方面。工程、建筑和其他许多需要具有创造性的领域中都使用模型。
表达模型的工具要求便于使用。建筑模型可以是图纸上所绘的建筑图,也可以是用厚纸板制作的三维模型,还可以用存于计算机中的有限元方程来表示。一个建筑物的结构模型不仅能够展示这个建筑物的外观,还可以用它来进行工程设计和成本核算。
软件系统的模型用建模语言来表达,如UML。模型包含语义信息和表示法,可以采取图形和文字等多种不同形式。建立模型的目的是因为在某些用途中模型使用起来比操纵实物更容易和方便。
2.2 模型的用途
模型有多种用途
1. 捕获精确和表达项目的需求和应用领域中的知识,以使各方面的利益相关者能够理解并达成一致
建筑物的各种模型能够准确表达出这个建筑物在外观、交通、服务设施、抗风和抗震性能,消费及其他需求。各方面的利益相关者则包括建筑设计师、建筑工程师、合同缔约人、各个子项目的缔约人、业主、出租者和市政当局。
软件系统的不同模型可以捕获关于这个软件的应用领域、使用方法、试题手段和构造模式等方面的需求信息。各方面的利益相关者包括软件结构设计师、系统分析员、程序员、项目经理、顾客、投资者、最终用户和使用软件的操作员。在UML中要使用各种各样的模型。
2. 进行系统设计
建筑设计师可以用画在图纸上的模型图、存于计算机中的模型或实际的三维模型使自己的设计结果可视化,并用这些模型来做设计方面的的试验。建造、修改一个小型模型比较简单,这使得设计人员不需花费什么代价就可以进行创造和革新。
在编写程序代码以前,软件系统的模型可以帮助软件开发人员方便地研究软件的多种构架和设计方案。在进行详细设计以前,一种好的建模语言可以让设计者对软件的构架有全面的认识。
3. 使具体的设计细节与需求分开
建筑物的某种模型可以展示出符合顾客要求的外观。另一类模型可以说明建筑物内部的电气线路、管线和通风管道的设置情况。实现这些设置有多种方案。最后确定的建筑模型一定是建筑设计师认为最好的一个设计方案。顾客可以对此方案进行检查验证,但通常顾客对具体的设计细节并不关心,只要能满足他们的需要即可。
软件系统的一类模型可以说明这个系统的外部行为和系统中对应于真实世界的有关信息,另一类模型可以展示系统中的类以及实现系统外部行为特性所需要的内部操作。实现这些行为有多种方法。最后的设计结果对应的模型一定是设计者认为最好的一种。
4. 生成有用的实际产品
建筑模型可以有多种相关产品,包括建筑材料清单、在各种风速下建筑物的偏斜度、建筑结构中各点的应力水平等。
利用软件系统的模型,可以获得类的声明、过程体、用户界面、数据库、合法使用的说明、配置草案以及与其他单位技术竞争情况的对比说明。
5. 组织、查找、过滤、重获、检查以及编辑大型系统的有关信息
建筑模型用服务设施来组织信息:建筑结构、电器、管道、通风设施、装潢等等。除非利用计算机存储,否则对这些信息的查找和修改没那么容易。相反,如果整个模型和相关信息均存储在计算机中,则这些工作很容易进行,并且可方便地研究多种设计方案,这些设计方案共享一些公共信息。
软件系统用视图来组织信息:静态结构视图、状态机视图、交互视图、反映需求的视图等等。每一种视图均是针对某一目的从模型中挑选的一部分信息的映射。没有模型管理工具的支持不可能使模型做得任意精确。一个交互视图编辑工具可以用不同的格式表示信息,可以针对特定的目的隐藏暂时不需要的信息并在以后再展示出来,可以对操作进行分组、修改模型元素以及只用一个命令修改一组模型元素等等。
6. 经济地研究多种设计过程中的解决方案
对同一建筑的不同设计方案的利弊在一开始可能不很清楚。例如,建筑物可以采用的不同的子结构彼此之间可能有复杂的相互影响,建筑工程师可能无法对这些做出正确的评价。在实际建造建筑物以前,利用模型可以同时研究多种设计方案并进行相应的成本和风险估算。
通过研究一个大型软件系统的模型可以提出多个实际方案并可以对它们进行相互比较。当然模型不可能做得足够精细,但即使一个粗糙的模型也能够说明在最终设计中所要解决的许多问题。利用模型可以研究多种设计方案,所花费的成本只是实现其中一种方案所花费的成本。
7. 利用模型可以全面把握复杂的系统
一个关于龙卷风袭击建筑物的工程模型中的龙卷风不可能是真实世界里的龙卷风,仅仅是模型而已。真正的龙卷风不可能呼之即来,并且它会摧毁测量工具。许多快速,激烈的物理过程现在都可以运用这种物理模型来研究和理解。
一个大型软件系统由于其复杂程度可能无法直接研究,但模型使之成为可能。在不损失细节的情况下,模型可以抽象到一定的层次以使人们能够理解。可以利用计算机对模型进行复杂的分析以找出可能的“问题点”,如时间错误和资源竞争等。在对实物做出改动前,通过模型研究系统内各组成部分之间的依赖关系可以得出这种改动可能会带来哪些影响。
2.3 模型的层次
针对不同目的,模型可以采取各种形式及不同的抽象层次。模型中所包含的信息量必须对应于以下几种目的:
1. 指导设计思路
在项目早期所建立的高层模型用于集中利益相关者的思路和强调一些重要的选择方案。这些模型描述了系统的需求并代表了整个系统设计工作的起点。早期的模型帮助项目发起者在把精力放在系统的细节问题之前研究项目可能的选择方案。随着设计工作的进展,早期模型被更为精确的模型所替代。没有必要详细保存早期研究过程中的种种选择方案和返工情况。早期模型的目的是帮助获得思路。但最后得到的“思路模型”要在进行详细设计前记录下来。早期模型不需要达到实现阶段的模型的精确程度,无须涉及有关系统实现的一套概念。建立这种模型只使用了UML定义的组件的一个子集,比后期的设计阶段的模型使用的组件要少得多。
当早期模型发展到具有一定精度的完整的视图模型时—例如,分析系统需求的模型—那么要在开发过程进入下一阶段时将其保存下来。不断向模型中填加信息的增量式开发(在这种情况下开发的推理过程也要保存和记录)与一般的针对“死端点”进行研究直到得出正确的解决方案的随意漫步式开发之间一个重要的区别。后一种情况通常使人不知怎么着手,并且根本没有必要对整个开发过程进行记录保存,除非遇到特殊情况需要对开发过程进行回溯。
2. 系统基本结构的抽象说明
在分析阶段和初步设计阶段所建立的模型以关键概念和最终系统的各种机制为中心。这些模型以某种方式与最终系统匹配。但是模型中丧失了细节信息,在设计过程中必需显式地补充这些信息。使用抽象模型的目的是在处理局部细节问题前纠正系统高层次的普遍问题。通过一个仔细的开发过程,这些模型可以发展成最终模型,该过程保证最终获得的模型能够正确实现初期模型的设计意图。必须具备跟踪能力来跟踪从基本模型到完备模型的过程,否则无法保证最终系统正确包含了基本模型所要表达的关键特性。基本模型强调语义,它们不需要涉及系统实现方面的细节。有时确实会出现这种情况:在低层实现方面的差别会使逻辑语义模糊不清。从基本模型到最后的实现模型的途径必须清晰和简明,不论这个过程由代码生成器自动实现还是由设计者人工实现。
3. 最终系统的详细规格说明
系统实现模型包含能够建造这个系统的足够信息,它不仅要包括系统的逻辑语义和语法、算法、数据结构和确保能正确完成系统功能的机制,而且还要包括系统制品的组织决定,这些制品对个人之间的相互协作和使用辅助工具来说十分必要。这种模型必须包括对模型元素进行打包的组件以便于理解和用计算机进行自动处理。这不是目标应用系统的特性,而是系统构造过程应具有的特性。
4. 典型或可能的系统范例
精心挑选的实例可以提高人们的观察能力并使系统的说明和实现有实际效果。然而,即使有非常多的例子,也起不到一段详细定义所起的效果。我们最终希望的是要让模型能够说明一般的情形,这也是程序代码所要做的事情。不过典型的数据结构、交互顺序或对象生命历程的例子对于理解复杂系统很有益处。必须小心使用例子。从逻辑上来说,从一大堆特例中归纳出最一般的情况是不可能的,但是大部分人思考某一问题时总是首先考虑一些被精心挑选出来的有关该问题的例子。范例模型仅是对模型的示例而不带有一般性的描述,因此,人们会觉得这两种模型之间有差异。范例模型一般只使用UML定义的组件的子集。说明型模型和范例模型在建模中都很有用。
5. 对系统全面的或部分的描述
模型可以完全描述一个独立系统,并且不需要参考外部信息。更通常的情况是,模型是用相互区别的、不连续的描述单元组织起来的,每个单元作为整体描述的一部分可以被单独进行存储和操纵。这种模型带有必须与系统其他模型联系在一起的散件。因为这些散件具有相关性和含义,因此它们能够与其他散件通过各种方式结合来构造不同的系统。获得重用是一个好的建模方法的重要目标。
模型要随时间发展变化。深度细化的模型源于较为抽象的模型,具体模型源于逻辑模型。例如,开始阶段建立的模型是整个系统的一个高层视图。随着时间的推进,模型中增加了一些细节内容并引入了一些变化。再随着时间的推进,模型的核心焦点从一个以用户为中心的前端逻辑视图转变成了一个以实现为中心的后端物理视图。随着开发过程的进行和对系统的深入理解,必须在各种层次上反复说明模型以获得更好的理解,用一个单一视角或线性过程理解一个大型系统是不可能的。对模型的形式无所谓“正确和错误”之分 。
2.4 模型内容
1. 语义和表示法
模型包含两个主要方面:语义方面的信息(语义)和可视化的表达方法(表示法)。
语义方面用一套逻辑组件表达应用系统的含义,如类、关联、状态、用例和消息。语义模型元素携带了模型的含义即,它们表达了语义。语义建模元素用于代码生成、有效性验证、复杂度的度量等,其可视化的外观与大多数处理模型的工具无关。语义信息通常被称作模型。一个语义模型具有一个词法结构、一套高度形式化的规则和动态执行结构。这些方面通常分别加以描述(定义UML的文献即如此),但它们紧密相关,并且是同一模型的一部分。
可视化的表达方式以可使人观察、浏览和编辑的形式展示语义信息。表示方式元素携带了模型的可视化表达方式,即语义是用一种可被人直接理解的方式来表达的。它们并未增添新的语义,但用一种有用的方式对表达式加以组织,以强调模型的的排例。因此它们对模型的理解起指导作用。表达式元素的语义来自于语义模型元素。但是,由于是由人来绘制模型图,所以表达式元素并不是完全来自于模型的逻辑元素。表达式元素的排列可能会表达出语义关系的另外含义,这些语义关系很不明显或模棱两可,以至于在模型中不能形式化地表达,但可给人启迪模。
2. 上下文
模型自身是一个计算机系统的制品,被应用在一个给出了模型含义的大型语境中。这个包括模型的内部组织、整个开发过程中对每个模型的注释说明、一个缺省值集合、创建和操纵模型的假定条件以及模型与其所处环境之间的关系。
模型需要有内部组织,允许多个工作小组同时使用某个模型而不发生过多的相互牵涉。这种对模型的分解并不是语义方面所要求的—与一个被分解成意义前后连贯的多个包的模型相比,一个大的单块结构的模型所表达的信息可能会同样精确,因为组织单元的边界确定会使准确定义语义的工作复杂化,故这种单块模型表达的信息可能比包结构的模型表达得更精确。但是要想有效地工作于一个大的单块模型上的多个工作组不彼此相互妨害是不可能的。其次,单块模型没有适用于其他情况的可重用的单元。最后,对大模型的某些修改往往会引起意想不到的后果。如果模型被适当分解成具有良好接口的小的子系统,那么对其中一个小的、独立的单元所进行的修改所造成的后果可以跟踪确定。不管怎样,将大系统分解成由精心挑选的单元所构成的层次组织结构,是人类千百年来所发明的设计大系统的方法中最可靠的方法。
模型捕获一个应用系统的语义信息,但还需记录模型自身开发过程中的各种信息,如某个类的设计者、过程的调试状态和对各类人员的使用权限的规定。这些信息至多是系统语义的外围信息,但对开发过程非常重要。因此,建立一个系统的模型必须综合考虑两方面。最简便的实现方法是将项目管理信息作为注释加入到语义模型中—,即可以对模型元素用非建模语言进行任意描述。在UML中用文本字符串来表示注释。
文本编辑器或浏览器所使用的命令不是程序设计语言的一部分,同样,用于创建和修改模型的命令也不是建模语言语义的一部分。模型元素的属性没有缺省值,在一个特定的模型中,它们均具有值。然而,对于实际的开发过程,人们要求建立与修改模型时无须详细说明有关的所有细节。缺省值存在于建模语言和支持这种语言的建模工具的边界处。在建模工具所使用的创建模型的命令中,它们是真正的缺省值,尽管它们可能会超过单个的建模工具并用户所期望的那样成为建模工具所使用的通用语言。
模型不是被孤立地建造和使用的。它们是模型所处的大环境中的一部分,这个大环境包括建模工具、建模语言和语言编译器、操作系统、计算机网络环境、系统具体实现方面的限制条件等等。系统信息应该包括环境所有方面的信息。系统信息的一部分应被保存在模型中,即使这些信息不是语义信息,例如项目管理注释(在上面已经讨论过)、代码生成提示、模型的打包、编辑工具缺省命令的设置。其他方面的信息应分别保存,如程序源代码和操作系统配置命令。即使是模型中的信息,对这些信息的解释也可以位于多个不同地方,包括建模语言、建模工具、代码生成器、编译器或命令语言等等。本书用UML自身对模型进行解释。但是当进行系统的具体物理实现时,要用到其他用于解释的资源,这些资源对UML来说是不可见的。
模型说明了什么?
一个模型是一个系统潜在配置的发生器;系统是它的范围,或值。按照模型来进行系统配置是一种理想化的情况。然而,有时模型所要求的种种条件在现实中无法实现。模型还是对系统含义和结构的一般性说明。这种描述是模型的范围,或含义。模型总是具有一定的抽象层次。它包含了系统中的最基本的成分而忽略了其他内容。对模型来说,有以下几方面需要考虑:
抽象和具体。 模型包含了系统的基本成分而忽略了其他内容。哪些是基本内容哪些不是基本内容需要根据建模的目的来判定。这不是说要把模型所含信息的精度一分为二,即只有精确和不精确两种情况。可能会存在一系列表达精度不同但逐渐提高的模型。建模语言不是程序设计语言。建模语言所表达的内容可能很不精确,因为多余的详细内容与建模目的无关。具有不同精度级别的模型可应用于同一个项目的各个阶段。用于程序设计编码的模型要求必须与程序设计语言有关。典型的情况是,在早期分析阶段使用高层次的,表达精度低的模型。随着开发过程的深入,所用的模型越来越细化,最终所使用的模型包含了大量的细节内容,具有很高的精度。
说明和实现。 一个模型可以告诉我们“做什么”(说明),也可以告诉我们“一个功能是如何实现的———即怎么做”(实现)。建模时要注意区分这两方面。在花大量时间研究怎么做之前很重要的一点就是要正确分析出系统要做什么。建模的一个重要的侧面是对具体实现细节进行抽象。在说明和实现之间可能有一系列相关关系,其中在某层次中的说明就是对它上一层次的实现。
阐述和举例。 模型主要是描述性的。模型所描述的是一个个实例,这些实例仅是作为例子才出现在模型中的。大部分实例仅在运行的一部分时间中才存在。有时,运行实例自身是对其他事物的描述。我们把这些混杂对象称做元模型(Metamodel)。更深一层次的看,认为任何事物不是描述性的就是实例性的,这种观点是不符合实际情况的。某一事物是实例还是描述不是孤立区分的,与观察角度有关,大部分事物都可以用多种角度来考察。
解释的变更。 用一种建模语言对模型可能会有多种的解释。可以定义语义变更点(semantic variation point)———可能会出现多种解释的地方———给每一个解释一个语义变更名,以便可以标识究竟使用了哪种解释。例如,Smalltalk语言的使用者要避免在系统实现模型种出现多重继承关系,因为Smalltalk语言不支持多重继承。而其他程序设计语言使用者可能会在模型种使用多重继承。语义变更点支持多种具体的实现过程