包图
- 格式:docx
- 大小:169.10 KB
- 文档页数:10
包图包图是在UML中用类似于文件夹的符号表示的模型元素的组合。
系统中的每个元素都只能为一个包所有,一个包可嵌套在另一个包中。
使用包图可以相关元素归入一个系统。
一个包中可包含附属包、图表或单个元素。
一个"包图"可以是任何一种的UML图组成,通常是UML用例图或UML 类图。
包是一个UML结构,它使得你能够把诸如用例或类之类模型元件组织为组。
包被描述成文件夹,可以应用在任何一种UML图上。
虽然包图并非是正式的UML图,但实际上他们是很有用处的,创建一个包图是为了∶描述你的需求高阶概述。
描述你的设计的高阶概述。
在逻辑上把一个复杂的图模块化。
组织Java源代码。
指南∶类包图创建类包图,以在逻辑上组织你的设计创建UML组件图,以在物理上组织你的设计把子包放置在母包的下面垂直地分层类包图用例包图创建用例包图,以组织你的需求在用例包图上包含角色水平地排列用例包图包包的命名要简单、具有描述性应用包是为了简化图包应该连贯在包上用版型注明架构层避免包间的循环依赖包依赖应该反映内部关系一、类包图1.创建类包图,以在逻辑上组织你的设计图1描述了一个组织成包的UML类图。
除了以下介绍的包原则之外,应用下列的规则来把UML类图组织到包图里:把一个框架的所有类放置在相同的包中。
一般把相同继承层次的类放在相同的包中。
彼此间有聚合或组合关系的类通常放在相同的包中。
彼此合作频繁的类,信息能够通过UML顺序图和UML合作图反映出来的类,通常放在相同的包中。
图1.一个类包图。
2.创建UML组件图,以在物理上组织你的设计。
如果你的组件比较接近技术,例如那些通过Enterprise Java Beans ( EJB)或Visual Basic的组件,你应该优先选择UML组件图来描述物理设计,而不是包图。
图1的版本源自于组件图章节中。
就像你看到的,这个图最适用于物理设计。
永远记住遵循敏捷建模(AM) ( Ambler 2002)的实践--应用合适的Artifact,为工作挑选最好的模型。
UML之包图包图的基本概念: 包图是⽤来描述模型中的包和所包含元素的组织⽅式的图,是维护和控制系统总体结构的重要内容。
包图能够组织许多UML中的元素,不过其最常⽤的⽤途是⽤来组织⽤例图和类图。
包图中包含包元素以及包之间的关系。
与其他图类似,包图中可以创建注解和约束。
包的概念: 包是⽤于把模型组织成层次结构的通⽤机制,它不能执⾏。
包名:包有简单名、路径名包中的元素:包中可以容纳各种⾼级的模型元素,如类和类的关系、状态机、⽤例图、交互、协作等,甚⾄是⼀个完整的UML图。
另外,包中还可以含有包,这被称为包的嵌套。
包元素的可见性:控制包外元素对包内元素的访问权限。
公有(+):只要当前包被引⼊,包内的公共元素即对引⼊者可见。
保护(#):仅对当前包的⼦包可见。
私有(-):仅对该包可见,外部⽆法访问。
另外,如果某元素对于⼀个包是可见的,则它对于嵌套在这个包中的任何包都是可见的。
包的构造型:可以使⽤构造型来描述包的种类。
UML预定义了⼀些构造型,⽤户也可⾃⾏定义新的构造型。
⾼内聚,低耦合:在外部观察包时,可以将内部元素视作⼀个整体,⽅便将多个元素⼀同处理。
包内部的元素应该保证有相似、相同的语义,或者其元素有同时更改和变化的性质。
注:在实际应⽤中,包对包含的元素的作⽤相当于C++和C#中命名空间的概念或Java中的包概念。
和这些概念不同的是,UML包中的内容不限于类和接⼝,包中的元素种类要丰富的多。
元素的分包原则:1)元素不能“狡兔三窟”:树形结构的⼀个节点不能同时拥有两个⽗节点,⼀个元素也不允许在两个包中重复出现。
2)相同包内元素不能重名:包所具有的命名空间的作⽤要求⽤⼀个包中的同种类元素名称必须是唯⼀的。
3)包内元素要紧密联系:分在同⼀个包中的元素应该具有某些相同的性质,即包的⾼内聚性。
4)包与包尽可能保持独⽴:包和包之间需要尽可能减少耦合度,要求包内元素与外部元素有尽可能少的依赖关系。
包的依赖关系:包之间的依赖关系实际上是从⼀个更⾼的层次来描述包内某些元素之间的依赖关系。
包图包图⼀、什么是包图包图的英⽂名为Package Diagram,Package这个英⽂单词有”将……打包“的意思,这个意思能恰好地表达包图的真正内涵。
包(Package)只是⼀个容器,他可以放任意的UML图进去(包括包图⾃⼰),⽽且⼀个包图内可以放⼊不同种类的UML图。
但要注意的是不同的UML⼯具对包图的⽀持程度不太⼀样,不⼀定能将任意的UML图放⼊包图。
⼆、语法包图可能是语法最简单的⼀种UML图,⼀个⽂件夹样⼦的东西就是⼀个包,包可以嵌套(层次不限),包之间最常见的关系是依赖(Dependency)关系。
包图⾥可以包含多个包,⽽包的嵌套层数是不受限制的。
三、应⽤场景包图是⼀个逻辑上的概念,⽽不是物理上的概念。
包图主要⽤来组织我们的思路,最常见的三种应⽤场景是:Ⅰ. ⽤包图组织类图有⼈喜欢⽤包图有条理德组织好类图,有⼈喜欢在⼀张巨⼤的类图中画出所有类,⽽我们喜欢⽤多张类图来表达。
其实不管怎样的表达⽅式,类及类之间的关系模型是唯⼀的,只是我们通过怎样的⾓度和⽅式进⾏展⽰⽽已。
那么⽤哪种⽅式表达最好呢?没有标准答案,完全取决与你,每个⼈都可以由属于⾃⼰的有效表达⽅式。
Ⅱ. ⽤包图组织⽤例⽤例太多很容易看晕,咋办?你可以⽤包图来组织⽤例,可以之将⽤例放⼊包中,也可以将执⾏这和⽤例都放⼊包中,但要注意的是,不是所有UML⼯具都⽀持你这样做的。
⽽我则很少⽤包图来组织⽤例图,我通常通过多个⽤例图,充分利⽤执⾏者的继承关系,以及⽤例的Extend和Include关系来组织好⽤例图。
Ⅲ. ⽤包图进⾏软件设计在我的实际⼯作当中,需求分析⼯作中⽤到包图的的机会不是很多,⽽在软件设计时经常⽤到包图,我们可以使⽤包图来进⾏软件架构设计,也可以综合应⽤包图、部署图、构件图来进⾏架构设计。
一个大型系统中往往包含了数量庞大的模型元素,如何组织管理这些元素是一个十分重要的问题。
包是一种常规用途的有效的组合机制。
包类似于文件系统中的文件夹或者是目录结构,它是一个容器,用来对模型元素进行分组,并且为这些元素提供一个命名空间。
UML中的一个包直接对应于Java中的一个包。
在Java中,一个包可能含有其他包、类或者同时含有这两者。
进行建模时,通常使用逻辑性的包,用于对模型进行组织。
而包图是由包和包之间的联系组成的,它是维护和控制系统总体结构的重要建模工具。
本章将详细介绍包图的各种概念、表示方法和实例应用。
1.包图的概念1.1包图和包当对大型系统进行建模时,经常需要处理大量的类、借口、构件、节点和图,这时就很有必要将这些元素进行分组,即把那些语义相近并倾向于一起变化的元素组织起来加入同一包中,这样便于理解和处理整个模型。
同时也便于控制包中元素的可见性。
包图是描述包及其关系的图。
与所有UML的其它图一样,包图可以包括注释、约束。
通过各个包与包之间关系的描述,展现出系统的模块与模块之间的关系。
图1是一个包图模型。
包是包图中最重要的概念,它包含了一组模型的元素和图,如图1中的Package A和Package B就是两个包。
Package BPackage A在面向对象软件开发的过程中,类显然是构建整个系统的基本元素。
但是对于大型的软件系统而言,其包含的类将是成百上千,再加上类间的关联关系、多重性等,必然是大大超出了人们对系统的理解和处理能力。
为了便于管理这些类,我们引入了“包”这种分组元素。
在包中可以拥有各种其它元素,包括类、接口、构件、节点、协作、用例,甚至是其它子包或图。
一个元素只能属于一个包。
包的作用是:1)对语义上相关的元素进行分组。
如,把功能相关的用例放在一个包中。
2)提供配置管理单元。
如,以包为单位,对软件进行安装和配置。
3)在设计时,提供并行工作的单元。
如,在设计阶段,多个设计小组,可以同时对几个相互独立包中的类进行详细设计。
4)提供封装的命名空间,同一个包中,其元素的名称必须惟一。
2.包的表示2.1包的表示法UML中,用文件夹符号来表示一个包。
包由一个矩形表示,它包含两栏。
下面是最常见的几种包的表示法,如图2所示。
Syste同其他的模型元素一样,每个包都必须有一个与其他包相区别的名称。
包的名称是一个字符串,标识包名称的格式通常有两种:简单名(simple name)和路径名(path name)。
其中,简单名仅包含一个名称字符串:路径名是以包处于的外围包的名字作为前缀并加上名称字符串。
例如,Rose 常用表示方法中,其包名UI 就是一个简单名。
而包System.Web.UI 才是一个完整带路径的名称,表示UI 这个包是位于System.Web 命名空间中的。
如图3所示。
2.3包的元素在一个包中可以拥有各种其他元素,包括类、接口、构件、节点、协作、用例,甚至是其他包或图。
这是一种组成关系,意味着元素是在这个包中声明的,因此一个元素只能属于一个包。
每一个包就意味着一个独立的命名空间,因此,两个不同的包,可以具有相同的元素名,但由于所位于的包名不同,因此其全名仍然是不同的。
在包中表拥有的元素时,有两种方法:一种是在第二栏中列出所属元素名,一种是在第二栏中画出所属元素的图形表示。
2.4包的可见性像类中的属性和方法一样,包中的元素也有可见性。
包内元素的可见性用来控制包外界元素访问包内部元素的权限。
可见性可分为三种。
1)公有访问(public ):包内的模型元素可以被任何引入了此包的其他包的内含元素访问。
公有访问用前缀于内涵元素名字的+号(+)表示。
2)保护访问(protected )此元素能被该模型包在继承关系上的后继模式包的内含元素访问。
保护访问用前缀于内涵元素名字的#号(#)表示。
3)私有访问(private )此元素可以被属于同一包的内含元素访问。
私有访问用前缀于内涵元素名字的—号(—)表示。
包内元素的可见性,标识了外部元素访问包内元素的权限。
表5-1列出了可见性与访问权限的关系。
2.5包的构造型为了表示包的新特性,用构造型来描述包的新特征。
包的构造型有5种,它们分别是:虚包(facade)、框架(framework)、桩(stub)、子系统(subsystem)和系统(system),3.包中的关系包图中包之间的关系有2种:依赖关系、泛化关系。
3.1依赖关系两个包之间存在依赖关系通常是指这两个包之间所包含的模型元素之间存在着一个和多个依赖。
对于由对象类组成的包,如果这两个包的任何对象类之间存在着如何一种依赖,那么这两个包之间就存在着依赖关系。
包的依赖关系同样是使用一根虚箭线来表示,虚箭线从依赖源指向独立目的的包,如下图所示。
图中,“飞机”包和“发动机包”之间存在依赖,因为“飞机”包所包含的任何类依赖于“发动机”包中所包含的任何类。
没有发动机,飞机就不能正常工作,这是非常明显的道理。
依赖关系又可以分为4种。
在依赖关系中,我们把箭尾端的包称为客户包,把箭头端的包称为提供者包。
下面以上图5-4为例说明其语义。
1. 《use》关系《use》关系是一种默认的依赖关系,说明客户包(箭尾端的包)中的元素以某种方式使用提供者包(箭头端的包)的公共元素,也就是说客户包依赖于提供者包。
如果没有指明依赖类型,则默认为《USE》关系。
例如在图5-4中,有两个《USE》依赖,Client包将通过Server包来完成Order的存储,而Server包使用System.Data.SqlClient包来实现数据库的存储。
2. 《import》关系《import》关系:最普遍的包依赖类型,说明提供者包的命名空间将被添加到客户包的命名空间中,客户包中的元素也能够访问提供者包的所有公共元素。
《import》关系使命名空间合并,当提供者包中的元素具有与客户包中的元素相同的名称时,将会导致命名空间的冲突。
这也意味着,当客户包的元素引用提供者包的元素时,将无需使用全称,只需使用元素名称即可。
例如在图5-4中,Client包引用了(import)了Rule包,Rule包又引用了GUI包。
同时,这还表示Client包间接引用了GUI包。
3. 《access》关系如果只想使用提供者包中的元素,而不想将两个包合并,则应使用该关系。
在客户包中必须使用路径名,才能访问提供者包中的所有公共元素。
4. 《trace》关系:想表示一个包到另一个包的历史发展,则需要使用《trace》关系来表示。
3.2泛化关系包间的泛化关系类似于类间的泛化关系,使用一般包的地方,可以用特殊包代替。
在系统设计中,对某一个特定的功能,有多种实现方法。
例如,实现多数据库支持;实现B/S和C/S双界面。
这时就需要定义一些高层次的“抽象包”和实现高层次功能的“实现包”。
在抽象包中定义一些接口和抽象类,在实现包中,定义一些包含实现这些抽象类和接口的具体类。
例如在图5-4中,说明GUI有两种风格:一种是基于WinForm的C/S风格,一种是WebForm的B/S风格。
需要注意的是,在《在UML用户手册》中将其归为泛化关系,而在《UML精粹》中却将其看作是实现关系。
4.阅读包图阅读包图的方法:(1)了解每个包的语义,它包含的元素语义;(2)理解包间的关系;(3)找到依赖关系复杂的包,从最复杂的包开始阅读,然后以此是简单的包。
例如,阅读下面的包图。
对上面包的理解如下:(1)根据《use》关系可以发现Client包使用Server包,Server包使用System.Data.SqlClient包,根据它们所包含的元素语义,可以得知Client包负责Order(订单)的输入,并通过Server包来管理用户的登录(LoggingService)和数据库存储(DataBase);而Server包还通过.Net的SQL SERVER 访问工具包,来实现与数据库的连接和通讯。
(2)看《import》关系,从RULE包所包含的元素语义可知,该包负责处理一些规则,并引用一个具体的窗体(Window);而Client包通过引用RULE来实现整个窗体和表单的显示,输入等,并且还将暂存Order(订单)信息。
(3)接着来看包的泛化关系。
GUI有两个具体实现:一个是针对C/S的WindowsGUI,一个是实现B/S的WebGUI。
绘制包图的基本过程主要有三个步骤:第一,寻找包;第二,确定包之间的关系;第三,标出包内元素的可见性。
绘制包图的“最小化系统间的耦合关系”的原则:最大限度减少包之间的依赖,包封装时,避免包之间的循环依赖;最小化每个包的public、protected元素的个数,最大化每个包中private元素的个数。
5.创建包图创建一个包图可以:(1)描述需求的高阶概述;(2)描述设计的高阶概述;(3)在逻辑上把一个复杂的图模块化;(4)组织源代码。
5.1寻找包通过把具有很强语义联系的建模元素分组,找出分析包。
分析包必须反映元素的真实的语义分组,而不仅是逻辑架构的理想视图。
我们以对象模型和用例模型为依据,把关系紧密的类分到同一个包中,把关系松散的类分到不同的包中。
1.标识候选包的原则:(1)把类图中关系紧密的类放到一个包中;(2)在类继承类层次中,把不同层次的类放在不同的包中。
也可以把用例模型作为包的来源。
然而,用例横跨分析包是非常普遍的——一个用例可以由几个不同包中的类实现。
2.调整候选包在已经识别一组候选包后,然后减少包间依赖,最小化每个包的public、protected 元素的个数,最大化每个包中private元素的个数。
做法是:(1)在包间移动类;(2)添加包或删除包。
良好包结构的关键是包内高内聚,包间低耦合。
通常,当创建分析包模型时,应该尽量使包模型简单。
获得正确的包集合比使用诸如包泛化和依赖构造型的特征更加重要,这些特征可以以后再添加,仅当使用诸如包泛化和依赖构造型的特征使得模型更加容易理解时,才使用这些包整理技术。
除了保持简单,还应该避免嵌套包。
物件在嵌套包结构中埋藏得越深,模型变得越晦涩。
作为经验法则,希望每个包具有4~10个分析类。
然而,对于所有的经验法则,却存在例外,如果打破某个法则使得模型更加清晰,就采用这个法则!有时,你必须引入只带有一个或者两个类的包,因为你需要断开包模型中的循环依赖。
在这种情况下,这是完全合理的。
5.2消除循环包依赖应该尽量避免包模型中的循环依赖。
如果包A 以某种方式依赖包B ,并且包B 以某种方式依赖包A ,就应该合并这两个包,这是消除循环依赖非常有效的方法。
但是经常起作用的、更好的方法是,努力分解公共元素成为第三个包C 。
重新计算依赖关系,以消除循环依赖。
示例显示在图5-6中。
5.3建立包图的具体做法建立包图的具体步骤如下:1) 分析系统模型元素(通常是对象类)。