6.1 包图的概念

包是一种常规用途的组合机制。UML中的一个包直接对应于Java中的一个包,C#中的命名空间。在Java中,一个包可能含有其他包、类或者同时含有这两者。进行建模时,通常使用逻辑性的包,用于对模型进行组织;使用物理性的包,用于转换成系统中的Java包。

C#命名空间与java包的区别分析

本文实例分析了C#命名空间与java包的区别。分享给大家供大家参考。具体分析如下:

相同点:

1、都是为了重用性(reusebility)——软件工程中一个非常重要的目标。

2、C#里面的命名空间和java中的包都属于访问权限的控制机制。

不同点:

1、C#命名空间只是一种逻辑上的结构,它允许所组织的类文件的物理存放位置与逻辑结构不一致,而Java中类文件的物理结构必须与逻辑结构一致。

2、Java的package本身没有子包的概念,所有package都是并列的关系,没有谁包含谁的问题。比如:org.dominoo.action和org.dominoo.action.asl之间绝对没有包与子包的关系。它们是各自独立的包,各自拥有自己的class/interface的集合。在org.dominoo.action.asl的某个java文件里,如果想引用org.dominoo.action里的某个class/interface,则必须import org.dominoo.action。

C++/C#的namespace方案则不然,一个namespace可以有自己的sub-namespace,我们不妨将namespace也称为package,那么C++/C#的package之间就可能存在包与子包的关系.

3、Java中使用import语句而C#中使用using namespace语句。

6.1.1 包图

包图是描述包及其关系的图。与所有UML的其它图一样,包图可以包括注释、约束。包间的关系有依赖关系和泛化关系。上图是一个典型的包图。

6.1.2 包的作用

在面向对象软件开发的过程中,类显然是构建整个系统的基本元素。但是对于大型的软件系统而言,其包含的类将是成百上千,再加上类间的关联关系、多重性等,必然是大大超出了人们对系统的理解和处理能力。为了便于管理这些类,我们引入了“包”这种分组元素。

包的作用是:

1.对语义上相关的元素进行分组。如,把功能相关的用例放在一个包中。

2.提供配置管理单元。如,以包为单位,对软件进行安装和配置。

3.在设计时,提供并行工作的单元。如,在设计阶段,多个设计小组,可以同时对几个相互独立包中的类进行详细设计。

4.提供封装的命名空间,同一个包中,其元素的名称必须惟一。

6.1.3 包中的元素

在包中可以拥有各种其它元素,包括类、接口、构件、节点、协作、用例,甚至是其它子包或图 。一个元素只能属于一个包。

命名方式

每个包必须有一个与其他包相区别的名称,包的名字是一个字符串:

  • 简单名:仅含一个简单的名称。

  • 路径名::以包所位于的外围包的名字作为前缀的包名

    1. 当不需要显示包的内容时,将包的名字放入主方框内;

    2. 需要显示内容时包的名字放入左上角的小方框中,将内容放入主方框内。

    3. 标以 {global} 的包叫通用包,表示系统的所有其他包都依赖于该包。

UML中,用文件夹符号来表示一个包。包由一个矩形表示,它包含2栏。下面是最常见的几种包的表示法

6.2.1 包的名称

每个包必须有一个与其他包相区别的名称。标识包名称的格式有两种:简单名和全名。

其中,简单名仅包含包一个简单的名称;全名是用该包的外围包的名字作为前缀,加上包本身的名字。

例如,Rose常用表示方法中,其包名UI就是一个简单名。而包System.Web.UI才是一个完整带路径的名称,表示UI这个包是位于System.Web命名空间中的。如图所示

6.2.2 包的元素

在一个包中可以拥有各种其他元素,包括类、接口、构件、节点、协作、用例,甚至是其他包或图。这是一种组成关系,意味着元素是在这个包中声明的,因此一个元素只能属于一个包。

每一个包就意味着一个独立的命名空间,因此,两个不同的包,可以具有相同的元素名,但由于所位于的包名不同,因此其全名仍然是不同的。

在包中表拥有的元素时,有两种方法:一种是在第二栏中列出所属元素名,一种是在第二栏中画出所属元素的图形表示(参见下图)。

6.2.3 包元素的可见性

像类中的属性和方法一样,包中的元素也有可见性,包内元素的可见性控制了包外部元素访问包内部元素的权限。

包的可见性有3种:可以用“+”来表示“public”,即,该元素是共有的;用“#”来表示“protected”, 即该元素是保护的,用“-”来表示“private”, 即,该元素是私有的。



包内元素的可见性,标识了外部元素访问包内元素的权限。表6-1列出了可见性与访问权限的关系。

表6-1 可见性与访问权限(假设包B中的元素访问包A中的元素)

6.2.4 包的构造型

为了表示包的新特性,用构造型来描述包的新特征。包的构造型有5种,下面分别说明。

1.《system》构造型:《system》构造型的包表示整个系统.

2.《subsystem》构造型:《subsystem》构造型的包则表示正在建模的系统中某个独立的子系统.

3.《facade》构造型:只是某个其它包的视图,它主要用来为其它一些复杂的包提供简略视图

4.《stub》构造型:是一个代理包,它服务于某个其他包的公共内容,这通常应用于分布式系统的建模中 .

5.《framework》构造型:用来表示一个框架的,框架是一个领域内的应用系统提供可扩充模板的体系结构模式

6.3 包图中的关系

包图中的关系有2种:依赖关系、泛化关系。

6.3.1 依赖关系

1.《use》关系

《use》关系是一种默认的依赖关系 ,说明客户包(箭尾端的包)中的元素以某种方式使用提供者包(箭头端的包)的公共元素,也就是说客户包依赖于提供者包。如果没有指明依赖类型,则默认为《USE》关系。

例如在图中,有两个《USE》依赖,Client包将通过Server包来完成Order的存储,而Server包使用System.Data.SqlClient包来实现数据库的存储。

2.《import》关系

《import》关系:最普遍的包依赖类型,说明提供者包的命名空间将被添加到客户包的命名空间中,客户包中的元素也能够访问提供者包的所有公共元素。

《import》关系使命名空间合并,当提供者包中的元素具有与客户包中的元素相同的名称时,将会导致命名空间的冲突。这也意味着,当客户包的元素引用提供者包的元素时,将无需使用全称,只需使用元素名称即可。

例如在上图中,Client包引用了(import)了Rule包,Rule包又引用了GUI包。同时,这还表示Client包间接引用了GUI包。



3.《access》关系

如果只想使用提供者包中的元素,而不想将两个包合并,则应使用该关系。在客户包中必须使用路径名,才能访问提供者包中的所有公共元素。

4.《trace》关系

想表示一个包到另一个包的历史发展,则需要使用《trace》关系来表示

6.3.2 泛化关系

包间的泛化关系类似于类间的泛化关系,使用一般包的地方,可以用特殊包代替。

在系统设计中,对某一个特定的功能,有多种实现方法。例如,实现多数据库支持;实现B/S和C/S双界面。这时就需要定义一些高层次的“抽象包”和实现高层次功能的“实现包”。

在抽象包中定义一些接口和抽象类,在实现包中,定义一些包含实现这些抽象类和接口的具体类。例如在上图中,说明GUI有两种风格:一种是基于WinForm的C/S风格,一种是WebForm的B/S风格。

需要注意的是,在《在UML用户手册》中将其归为泛化关系,而在《UML精粹》中却将其看作是实现关系。

6.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.

6.5 创建包图

绘制包图的基本过程主要有三个步骤:第一,寻找包;第二,确定包之间的关系;第三,标出包内元素的可见性。

绘制包图的“最小化系统间的耦合关系”的原则:

最大限度减少包之间的依赖,包封装时,避免包之间的循环依赖;最小化每个包的public、protected元素的个数,最大化每个包中private元素的个数。

6.5.1 寻找包

通过把具有很强语义联系的建模元素分组,找出分析包。分析包必须反映元素的真实的语义分组,而不仅是逻辑架构的理想视图。

我们以对象模型和用例模型为依据,把关系紧密的类分到同一个包中,把关系松散的类分到不同的包中。

1.标识候选包的原则:

(1).把类图中关系紧密的类放到一个包中;

(2).在类继承类层次中,把不同层次的类放在不同的包中。

也可以把用例模型作为包的来源。然而,用例横跨分析包是非常普遍的——一个用例可以由几个不同包中的类实现。

2.调整候选包

在已经识别一组候选包后,然后减少包间依赖,最小化每个包的public、protected元素的个数,最大化每个包中private元素的个数。做法是:

(1).在包间移动类;

(2).添加包或删除包。

良好包结构的关键是包内高内聚,包间低耦合。

通常,当创建分析包模型时,应该尽量使包模型简单。获得正确的包集合比使用诸如包泛化和依赖构造型的特征更加重要,这些特征可以以后再添加,仅当使用诸如包泛化和依赖构造型的特征使得模型更加容易理解时,才使用这些包整理技术。除了保持简单,还应该避免嵌套包。物件在嵌套包结构中埋藏得越深,模型变得越晦涩。

作为经验法则,希望每个包具有4~10个分析类。然而,对于所有的经验法则,却存在例外,如果打破某个法则使得模型更加清晰,就采用这个法则!有时,你必须引入只带有一个或者两个类的包,因为你需要断开包模型中的循环依赖。在这种情况下,这是完全合理的。

6.5.2 消除循环包依赖

应该尽量避免包模型中的循环依赖。如果包A以某种方式依赖包B,并且包B以某种方式依赖包A,就应该合并这两个包,这是消除循环依赖非常有效的方法。但是经常起作用的、更好的方法是,努力分解公共元素成为第三个包C。重新计算依赖关系,以消除循环依赖。示例显示在图中。

很多建模工具允许自动验证包间依赖。如果一个包中的元素访问另一个包中的元素,但两个包间却没有依赖关系,那么工具产生访问冲突列表。

在分析模型中,不可能创建没有访问冲突的包图。

6.6 包图建模

包图主要用于两种不同层次的用途:一是对成组元素建模;二是对体系结构建模。

6.6.1 对成组元素建模

对成组元素进行建模可以说是包图最常见的用途,它将建模元素组织成组,然后对组进行命名,在对成组元素建模时,应遵循以下几个策略:

每个包都应该是由在概念上,语义上相互接近的元素组成。

对于每个包,找出应标记为公共的元素,但应尽可能地少。

一般使用默认的《use》构造型,在实现类时,才用《import》构造型代替《use》构造型。

采用泛化来对特殊包进行建模。

在构建包模型时,注意,在包中只标明对每个包起核心作用的元素;另外业可以标识每个包的文档标记值,以使其更加清晰。

6.6.2 对体系结构建模

体系结构是一个软件系统的核心逻辑结构,常用的体系结构模式包括分层、MVC、管道、黑板、微内核等,而在应用软件中,分层和MVC是最常见的两种结构。

在分层的体系结构中,最常见的划分是表示层(present)、逻辑层(business或domain)、数据层(包括数据访问、日记等)。如果采用分层体系结构,我们就把每一层用一个包来表示,如图所示



图 用包分层

UML 包图 详细介绍的更多相关文章

  1. UML类图详细介绍

    类图主要描述程序对象以及他们之间的关系.一般来说,类.接口.抽象类这些程序对象的区别很容易,但是他们之间六种关系以前总是理解不够深刻,这次进行了一次复习,顺便写成博文以便加深理解 类图中的三种对象 类 ...

  2. UML和模式应用5:细化阶段(8)---逻辑架构和UML包图

    1.前言 本章是从面向分析的工作过度到软件设计 典型的OO系统设计的基础是若干架构层,如UI层.应用逻辑(领域)层 本章简要考察逻辑分层架构和相关UML表示法 2.逻辑架构和层 逻辑架构 逻辑架构是软 ...

  3. Python设计模式 - UML - 包图(Package Diagram)

    简介 包图是对各个包及包之间关系的描述,展现系统中模块与模块之间的依赖关系.一个包图可以由任何一种UML图组成,可容纳的元素有类.接口.组件.用例和其他包等.包是UML中非常常用的元素,主要作用是分类 ...

  4. Fiddler抓包工具详细介绍

    本文转自:http://www.cnblogs.com/Chilam007/p/6985379.html 一.Fiddler与其他抓包工具的区别 1.Firebug虽然可以抓包,但是对于分析http请 ...

  5. UML顺序图知识点介绍(Sequence Diagram)

    消息 调用消息 调用(procedure call)消息的发送者把控制传递给消息的接收者,然后停止活动,等待消息接受者放弃会返回控制 在Rational Rose(2016版本如图所示) 异步消息 异 ...

  6. UML类图简单介绍

    先上一张图: 概述 类图(Class Diagram)是面向对象系统建模中最常用和最重要的图,是定义其它图的基础.类图主要是用来显示系统中的类.接口以及它们之间的静态结构和关系的一种静态模型. 类图组 ...

  7. UML类图介绍(转载)

    UML类图详细介绍   类图主要描述程序对象以及他们之间的关系.一般来说,类.接口.抽象类这些程序对象的区别很容易,但是他们之间六种关系以前总是理解不够深刻,这次进行了一次复习,顺便写成博文以便加深理 ...

  8. UML类图的6大关系

    <小酌重构系列>已经完成了大约1/3了,在这些文章中,我使用了一些简单的类图来描述重构策略.在之后的文章中,我可能会借助稍微复杂一些的UML类图来介绍.但是在此之前,我觉得有必要先介绍一下 ...

  9. UML-逻辑架构&包图-相关概念

    1.逻辑架构 软件的宏观组织结构.含: 1).包 2).子系统 3).层 2.层 对类.包.子系统的分组(内聚).例如:mvc.在OOA/D中要重点关注核心应用逻辑(或领域)层. 3.UML包图 描述 ...

随机推荐

  1. VUE3 之 组件传参

    1. 概述 韦奇定律告诉我们:大部分人都很容易被别人的话所左右,从而开始动摇.怀疑,最终迷失自我.因此我们要努力的坚定信念,相信自己,才不会被周围的环境所左右,才能取得最终的胜利. 言归正传,之前我们 ...

  2. 新手如何入门linux,linux原来还可以这么学

    前言 在这个只有cangls和小白两人的小房间中,展开了一次关于学习方法的讨论. 小白:cangls啊,我想请教一个问题,您是如何记住那么多linux命令的. cangls:我啊,别人都看我的小电影, ...

  3. 『无为则无心』Python函数 — 39、Python中异常的传播

    目录 1.异常的传播 2.如何处理异常 1.异常的传播 当在函数中出现异常时,如果在函数中对异常进行了处理,则异常不会再继续传播.如果函数中没有对异常进行处理,则异常会继续向函数调用者传播.如果函数调 ...

  4. ForkJoinPool简单使用

    简介 ForkJoinPool的优势在于,可以充分利用多cpu,多核cpu的优势,把一个任务拆分成多个"小任务",把多个"小任务"放到多个处理器核心上并行执行, ...

  5. Plist存储

  6. @property中的copy关键字

    1.@property中的copy的作用 防止外界修改内部的值 @interface Person : NSObject @property (nonatomic, retain) NSString ...

  7. LAMP以及各组件的编译安装

    LAMP以及各组件的编译安装 目录 LAMP以及各组件的编译安装 一.LAMP 1. LAMP概述 2. 各组件的主要作用 3. 平台环境的安装顺序 二.编译安装apache httpd 1. 关闭防 ...

  8. 【译】System.Text.Json 的下一步是什么

    .NET 5.0 最近发布了,并带来了许多新特性和性能改进.System.Text.Json 也不例外.我们改进了性能和可靠性,并使熟悉 Newtonsoft.Json 的人更容易采用它.在这篇文章中 ...

  9. C++改变数组长度

    C++改变数组长度 代码 //改变数组长度 #ifndef CHANGELENGTH1D_H #define CHANGELENGTH1D_H #include<stdexcept> #i ...

  10. 用Java模拟实现对系统文件以目录的拷贝功能

    要用Java对单个文件拷贝的话,其实思路很简单,循环读取被拷贝文件,放入byte数组,然后写入目标文件.当然我们也可以借助现有的类去完成,如InputStream中的transferTo()方法就可以 ...