C# UML基础

面向对象编程方法学是C#编程的指导思想。进行C#编程的第一步是利用对象建模技术(Object Modeling Technique,OMT)来分析目标问题,抽象出相关对象的共性,对它们进行分类,并分析各类之间的关系,再用类来描述同一类对象,归纳出类之间的关系。Coad和Yourdon在对象建模技术、面向对象编程和知识库系统的基础之上设计了一整套面向对象的方法,分为面向对象分析(Object- Oriented Analysis,OOA)和面向对象设计(Object-Oriented Design,OOD)。对象建模技术、面向对象分析和面向对象设计共同构成了系统设计的过程,如图6-1所示。这是编写代码的基础。
系统设计流程
在进行对象建模、面向对象分析和设计的过程中,需要使用建模语言来描述分析的过程和结果。统一建模语言(Unified Modeling Language,UML)是为了这个目标而设计的一种标准通用的设计语言。任何想要真正理解面向对象编程思想的人,都需要具备一定的UML知识。
UML不是一种方法学,而是一种描述语言,它提供了多种类型的模型描述图(diagram),当在某种给定的方法学中使用这些图时,人们就能更容易理解和交流设计思想。UML的图可划分为如下三种类型。
— 静态图(static diagram):描述了那些不发生变化的软件元素的逻辑结构,描绘了类、对象、数据结构及其存在于它们之间的关系。
— 动态图(dynamic diagram):展示了在运行期间的软件实体的变化,描绘了执行流程、实体改变状态的方式。
— 物理图(physical diagram):显示了软件实体的不变化的物理结构,描绘库文件、字节文件、数据文件等,以及存在于它们之间的关系。
表6 -1说明了三类图中最常用的一些UML图,以及它们适用的软件开发阶段。本节将主要介绍其中的用例图(use case diagram)、类图(class diagram)、对象图(object diagram)、序列图(sequence diagram)、状态图(statechart diagram)、活动图(activity diagram)、组件图(component diagram)和部署图(deployment diagram)。
表6-1  常用的UML图
   
   
分析阶段
设计阶段
实现阶段
静态图
用例图
ü
 
 
 
对象图
ü
ü
 
 
类图
ü
ü
ü
 
组件图
 
ü
ü
 
部署图
 
 
ü
动态图
协作图
ü
ü
ü
 
序列图
ü
ü
ü
 
活动图
ü
 
 
 
状态图
ü
ü
ü
物理图
文件、数据库等
ü
ü
ü
提示  Microsoft Visio可以用来方便地绘制UML图。Visual Studio 2005的类关系图也可以显示类似UML的图,但是与标准的UML稍有不同。
 用例图
用例图描述了系统提供的一个功能单元。用例图的主要目的是帮助开发团队以一种可视化的方式来理解系统的功能需求,包括基于基本流程的“角色”之间的关系,以及系统内用例之间的关系。用例图一般用于表示用例的组织关系,要么是整个系统的全部用例,要么是完成具有功能(例如,所有安全管理相关的用例)的一组用例。
用例(use case)指的是系统的功能,它是系统某个功能的所有执行动作的集合。用例是从一个用户的观点来描述的。这个用户告诉系统去做一些特定的事情。一个用例捕获一个事件的可视化序列,这个事件是一个系统对单个用户的激励(stimulus)的响应过程。
动作者(actor)表示系统用户能扮演的角色(role) 。这些用户可能是人,也可能是其他的计算机、一些硬件,或者甚至是其他的软件系统。对用例的唯一要求是,它们必须位于用例描述的系统部分之外,它们必须能刺激系统部分,并接收返回。
用例描述了当动作者之一给系统特定的刺激时的系统活动。这些活动用文本来描述。它描述了触发用例的刺激的本质,输入和输出到其他活动者,以及从输入到输出的活动。用例文本通常也描述每一个活动可能的错误和系统应采取的补救措施。
在用例图中,用椭圆来表示用例,并将用例的名称放在椭圆的中心或椭圆下面的中间位置。人形符号用来表示角色(用户)。角色和用例之间的关系使用简单的线段来描述,表示角色可以操作此用例。
在用例图中,用一个方框来表示系统的边界。所有系统用例都放在框内,所有动作者都位于框外。动作者和用例之间用直线相连。方框内的每一件事物都是系统的一部分,方框外的每一件事物都是系统的外部。用例图也可以表示方框内的系统用例之间的关系,最常见的是“使用关系”,用带箭头的直线来表示,箭头指向被使用的用例。还有一种关系是扩展关系,用来表示继承。
图6-2显示了一个用例图。用例图通常用于表达系统或者系统范畴的高级功能。在图中可以很容易地看出该系统所提供的功能。这个系统允许乐队经理查看乐队CD的销售统计报告及排行榜报告。它也允许唱片经理查看特定CD的销售统计报告和这些CD在排行榜的报告。这个图还告诉我们,系统将通过一个名为“排行榜报告服务”的外部系统来提供排行榜报告。
用例图不会列出系统不能完成的功能。例如,图6-2所示的系统不能提供给乐队经理收听排行榜上不同专辑中的歌曲的方法,也就是说,系统没有引用一个叫做“收听排行榜上的歌曲”的用例。如果在用例图中提供清楚的、简要的用例描述,项目赞助商就能很容易地看出系统是否提供了必需的功能。
图6-2  用例图示例
6.1.3  类图和对象图
类图表示不同的实体(人、事物和数据)如何彼此相关,显示了系统的静态结构。类图可用于表示逻辑类,逻辑类通常就是业务人员所谈及的事物种类,比如摇滚乐队、CD、广播剧,或者贷款、住房抵押、汽车信贷及利率的抽象描述。类图还可用于表示实现类,实现类就是程序员要编写的类。实现类图与逻辑类图可能会用来描述一些相同的类。然而,实现类图与逻辑类图不会使用相同的描述属性。
类图是一个分为三个部分的矩形。最上面的部分显示类的名称,中间部分显示类的属性,最下面的部分显示类的操作(或者说“方法”)。实际上,最常用、最简单的类图就是一个在里面显示了类名的长方形,因为在UML中,大多数类只要有一个能够清楚表达的命名就可以了。
在类名部分还可以显示类的构造类型。类的构造型显示在一对双角括符号“« »”之间,经常放在类的名称上面。常见的构造类型包括实现类(直接显示类名)、接口(在类名上面显示 «interface»),以及工具类(在类名上面显示 «utility»)。如果类名用斜体表示,或者在类名下面标上{abstract},就表示这个类是一个抽象类。
在属性和方法的前面有一个字符用来表示属性或方法的作用域,它们的意义如下:
—“-”表示属性或方法是私有的(private);
—“#”表示属性或方法是保护的(protected);
—“+”表示属性或方法是公用的(public)。
紧接在属性或方法的参数名称的冒号(:)号之后,显示了属性的类型或方法的参数的类型。方法的返回值类型显示在方法后面的冒号之后。
图6-3显示了一个类Person的类图,它对应的类的C#源代码如下:
Person
+ name: string
+ sex: char
- age: int
+ Work(in type: string): void
+ Person(in name: string, in sex: char, in age: int): void
+ Speak(): void
+ Eat(): void
图6-3  类图示意
class Person
{
    public string name;
    public char sex;
    private int age;
    public Person(string name, char sex, int age)
    {
    }
    public void Eat()
    {
    }
    public void Speak()
    {
    }
    public void Work(string type)
    {
    }
}
对象图用来表示类的实例化对象。对象图用一个两层的矩形来表示,上层标识对象名和类名,下层标识对象的实例化属性值。下面的代码将创建一个Person类的对象mary:
Person mary = new Person("Mary", 'F', 24);
对象mary的对象图如图6-4所示。
mary: Person
name: string   = "Mary"
sex: char      = 'F'
age: int       = 24
图6-4  对象图示例
在一个系统中,类之间存在多种关系,如下所示。
— 继承(inheritance):继承是指一个类从其父类派生而来,继承了父类的属性和方法。基于类的继承叫做一般化(generalization),基于接口的继承,叫做实现(realization)。
— 关联(association):类之间的关联大多用来表示变量实例持有对其他对象的引用,这种关系是半永久的,但没有包含关系。
— 依赖(dependency):依赖是不同类的实例之间的暂时关系。
— 聚合(aggregation):聚合是关联的一种特殊形式,它意味着一种整体/部分(whole/part)的关系,但是部分也可以作为其他整体的组分,而且部分和整体之间也没有生命期的依赖。
— 组合(composition):组合是聚合的一种特殊形式,组合的关联性比聚合更强,部分只能作为唯一的一个整体的部分,而且部分的生命周期依赖于整体的生命周期。
UML类图对这些关系的表示方法如图6-5所示。具有关联、聚合和组合关系的两个对象之间可能是没有数量关系的一种联系,也可能存在数量关系,比如1对1(不标识)、0个或1个(标识为0…1)、0个或多个(标识为0…*或0… n)、1个或多个(标识为1…*或1… n)或者确切的数字(直接标识数字)。
图6 -6显示了一个包含了图6-2中的对象的类图。其中包括一个继承关系和两个关联关系。CDSalesReport类继承自Report类。一个 CDSalesReport类与一个CD类关联,但是CD类并不知道关于CDSalesReport类的任何信息。CD类和Band类都彼此知道对方,两个类彼此都可以与一个或者多个对方类相关联。
图6-5  UML类图之间的关系表示方法
图6-6  包含关系的类图
图6 -7显示了一个包含多种关系的类图的另一个例子。Person类实现了IHuman接口,Author类继承了Person类;Book类与Author 类之间的关联是1对多的,即一本书可能有一个或多个作者;Person读书,这是一种暂时的单向依赖;Book由一个或多个Page组成,每一个Page 只能作为一本Book的一部分,这是一种组合关系;Bookshelf里可以不放或者放多本Book,Book也可以放在其他的Bookshelf中, Bookshelf的存在并不能影响Book的存在性,这是一种聚合关系。
图6-7  一个包含多种关系的类图
表示各对象之间的关系的对象图说明了系统在某一个特定时刻的状态,经常叫做系统的快照(snapshot)。
 内幕:UML与源代码
UML是一种设计语言,它的目的不是表现细节,而是表现结构,仅仅展示必要的细节。因此,UML不可能与源代码一一对应,只存在结构上的对应关系。作为一种参考,下面列出了图6-7中的类图的C#源代码:
interface IHuman
{
}
class Person : IHuman
{
    void Read(Book book)
    {
         // …
    }
}
class Author : Person
{
    public Book[] books;
}
class Book
{
    public Author author;
    public Page[] pages;
}
class Page
{
}
class Bookshelf
{
    public Book[] books;
}
序列图
序列图显示具体用例(或用例的一部分)的详细流程。它几乎是自描述的,并且显示了流程中不同对象之间的交互关系,同时还可以很详细地显示对不同对象的各种调用。
序列图有两个维度:垂直维度以发生的时间顺序显示消息/调用的序列;水平维度显示对象实例之间的交互。
对象之间的交互包括:
— 调用(call):一个对象调用另一个对象(或者自己)的方法。
— 返回(return):返回一个值作为方法调用的结果。
— 发送(send):一个对象给另一个对象(或者自己)异步发送一个消息。
— 创建(create):一个对象实例化另一个对象。
— 销毁(destroy):一个对象销毁另一个对象(或者自己)。
序列图的绘制非常简单。图的顶部的框表示类的实例(对象)。在框中,类实例名称和类名称之间用空格/冒号/空格来分隔(例如,gen : ReportGenerator)。如果某个类实例向另一个类实例发送一条消息,则绘制一条具有指向接收类实例的开箭头的连线,并把消息/方法的名称放在连线上面。对于某些特别重要的消息,可以绘制一条具有指向发起类实例的开箭头的虚线,将返回值标注在虚线上。包括返回值的虚线,有助于序列图的阅读。
阅读序列图也非常简单。从左上角启动序列的“驱动”类实例开始,然后顺着每条消息往下阅读。
图6 -8显示了一个序列图的例子。图中的序列图显示了许多的细节(比如,其中显示了每条被发送消息的返回消息,这是可选的),一般的序列图可能要简单得多。通过阅读这个序列图,就能明白如何创建一个CD销售报告。其中的aProc对象表示驱动类实例。aProc向名为gen的ReportGenerator类实例发送一条消息。该消息被标为generateCDSalesReport,表示ReportGenerator对象实现了这个消息处理程序。进一步理解可发现,generateCD SalesReport消息标签在括号中包括了一个cdId,表明aServlet随该消息传递一个名为cdId的参数。当gen实例接收到一条 generateCDSalesReport消息时,它会接着调用CDSalesReport类,并返回一个aCDReport的实例。然后gen实例对返回的aCDReport实例进行调用,在每次消息调用时向它传递参数。在该序列的结尾,gen实例向它的调用者aProc返回一个aCDReport。
图6-8  序列图示例
 状态图
状态图表示某个类所处的不同状态和该类的状态转换信息。每个类都有状态,但不是每个类都应该有一个状态图。只有当行为的改变和状态有关时才创建状态图。一般只描述在系统活动期间具有三个或更多潜在状态的类的状态图。
状态图的符号集包括5个基本元素:初始起点,它使用实心圆来绘制;状态之间的转换,它使用带箭头的线段来绘制;状态,它使用圆角矩形来绘制;判断点,它使用空心圆来绘制;一个或者多个终止点,它们使用内部包含实心圆的圆来绘制。要想绘制状态图,首先需要绘制起点和一条指向该类的初始状态的转换线段。状态本身可以在图上的任意位置绘制,然后只需使用状态转换线条将它们连接起来。
图6-9显示了一个培训班的状态图。图的中心有一个判断点,如果有学员退学,则需要判断是否还有学员继续学习:如果还有,则培训班继续,否则只好被迫停止。
图6-9  一个培训班的状态图
6.1.6  活动图
活动图表示在处理某个活动时,两个或者更多类对象之间的过程控制流。活动图可用于在业务单元的级别上对更高级别的业务过程进行建模,或者对低级别的内部类操作进行建模。
活动图的符号集与状态图中使用的符号集类似。像状态图一样,活动图也从一个连接到初始活动的实心圆开始。活动是通过一个圆角矩形(活动的名称包含在其内)来表示的。活动可以通过转换线段连接到其他活动,或者连接到判断点,这些判断点连接到由判断点的条件所保护的不同活动。结束过程的活动连接到一个终止点(就像在状态图中一样)。作为一种选择,活动可以分组为泳道(swimlane),泳道用于表示实际执行活动的对象。
图6 -10中显示的活动图有两个泳道,因为有两个对象控制着各自的活动:乐队经理和报告工具。整个过程首先从乐队经理选择查看他的乐队销售报告开始。然后报告工具检索并显示他管理的所有乐队,并要求他从中选择一个乐队。在乐队经理选择一个乐队之后,报告工具就检索销售信息并显示销售报告。该活动图表明,显示报告是整个过程中的最后一步。
图6-10  活动图示例
6.1.7  组件图
组件图提供系统的物理视图,它的用途是显示系统中的软件与其他软件组件(例如,库函数)的依赖关系。组件图可以在一个非常高的层次上显示,从而仅显示粗粒度的组件,也可以在组件包层次上显示。
图6 -11中的组件图显示了四个组件:Reporting Tool、Billboard Service、ASP .NET和ADO .NET。从Reporting Tool组件指向Billboard Service、ASP .NET API和ADO .NET组件的带箭头的线段,表示Reporting Tool依赖于那三个组件。
6.1.8  部署图
部署图表示该软件系统如何部署到硬件环境中。它的用途是显示该系统不同的组件将在何处物理地运行,以及它们将如何彼此通信。因为部署图是对物理运行情况进行建模,系统的生产人员就可以很好地利用这种图。
部署图中的符号包括组件图中所使用的符号元素,另外还增加了几个符号,包括节点的概念。一个节点可以代表一台物理机器,或代表一个虚拟机器节点(例如,一个大型机节点)。用三维立方体来表示节点,节点的名称位于立方体的顶部。所使用的命名约定与序列图中相同:[实例名称] : [实例类型](例如,"w3.reporting.myco.com : Application Server")。
图6-11  组件图示例
图6 -12中的部署图表明,用户使用运行在本地机器上的浏览器访问Reporting Tool,并通过公司intranet上的HTTP协议连接到Reporting Tool组件。这个工具实际运行在名为w3.reporting.myco.com的服务器上。Reporting Tool通过ADO .NET与数据库相连。除了与报告数据库通信外,Report Tool组件还通过HTTPS上的SOAP与Billboard Service进行通信。


Trackback: http://tb.blog.csdn.net/TrackBack.aspx?PostId=1926520

http://blog.csdn.net/lanpeng/archive/2007/12/10/1926520.aspx

 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值