目录
1. 关联关系——association(表示方法 —— )
2. 依赖关系——dependency (表示方法 - - - - - - - > )
5. 实现关系 realize (表示方法 A实现B )
7. 泛化关系 generalization (表示方式 )
3.5 时序图——用于描述按时间顺序排列的对象之间的交互模型
一、 为什么需要uml
1.1.1 从现实世界到业务模型
1. 参与者
参与者(actor):模型信息的提供者
2. 用例
用例(use case):元模型的业务目标,即现实世界中的“事”
3.分析模型
分析模型(analysis module):uml通过被概念化的过程来建立适合计算机理解和实现的模型,这个模型叫做分析模型。
- 边界类(boundary )——边界决定了外面可对里面做什么事。边界类代表原始需求中的“事”
- 实体类(entity )—— 映射了现实世界中参与者完成业务目标所涉及的事物。实体类代表现实世界中的“物”
- 控制类(control)——边界和实体都是静态的。uml采用控制类来表述原始需求中的动态信息,即业务或者用例场景中的步骤活动。控制类代表了现实世界中的“规则”
4. 业务模型到概念模型的转换过程
5. 从概念模型到设计模型
设计模型的工作就是制造零部件,组装汽车的过程。在设计模型中,概念模型中的
- 边界类——可以被转化为操作界面或者系统接口
- 控制类——可以被转换为计算程序或者控制程序
- 实体类——可以被转化为数据库表、xml文档或者其他可持久特征的类
转化过程需要遵循的原则:
- 软件构架和框架——软件构架和框架规定了实现类必须实现的接库、必须继承的超类、必须遵守的编程规则等
- 编程语言——不同的编程语言会有不同的设计要求
- 规范或者中间件——实现类要遵循规范或中间件规定的那些必须特性。
6. 面向对象设计分析的完整过程
1.2 建模基础
1.2.1 用例驱动
要解决问题领域就要归纳出所有必要的抽象角度(用例),为这些用例描述出可能的特定场景,并找到实现这些场景的事物、规则和行动。
在统一过程中,一个用例就饿死一个分析单元、设计单元、开发单元、测试单元甚至是部署单元。
用例可驱动的内容:
- 逻辑视图——系统只有一个逻辑视图,该视图以图形方式说明关键的用例实现、子系统、包和类,他们包含在构架方面具有重要意义的行为,即建模公式中的那些“人”、“事”、“物”、“规则”是如何分类组织的。
- 进程视图——系统只有一个进程视图,他以图像方式说明了系统中进程的详细组织结构,其中包括类和子系统到进程和线程的映射。
- 部署视图——系统只有一个部署视图,他以图形方式说明了处理活动在系统中各个节点的分布,包括进程和线程的物理分布,即建模公式中那些那些“人”、“事”、“物”、“规则”是如何部署在物理节点(主机、网络环境)上的。
- 实施视图——作用是获取为实施指定的架构决策。实施视图通常包含以下内容:
- - 列举实施模型中的所有自信同
- - 描述子系统如何组值为层次和分成结构的构建图
- - 描述子系统见的导入和以来关系图
- 实施视图用于
- - 为个人、团队分配实施工作
- - 估算要开发、修改或删除的代码量
- - 阐述大规模服用的理由
- - 考虑发布策略
1.2.2 抽象层次
抽象层次有两种方法
- 自顶向下——适用于让人们从头开始认识一个事物
- 自底向上——适用于在时间中改进和提高认识。
1.2.3 视图
建模的目的是向相关的人通过不同的视角展示他们想要了解的信息。UML图中的用例图、对象图、类图、包图等不同的视图,从不同方面描述了软件的结构和组成。建模最主要的工作就是为软件绘制那些表达软件含义的视图,开完整的表达软件的含义。
1.2.4 对象分析方法
面向对象的思想
- 一切皆对象
- 对象都是独立的——
对象间相互独立,只在特定场景下才会产生关联关系。我们获取和分析对象的手段经常是通过分析某个场景。对象不因为该场景而存在,场景中的对象只是对象映射到该场景中的一个侧面,我们称为一个对象的实例,通过场景,我们只能获取对象的一个侧面信息。
-
对象具有原子性
-
对象都是可抽象的——对象所参与的场景越多,对象越有抽象价值。在分析过程中,应该关注那些参与了很多场景的对象。
-
对象具有层次性——层次越高,则描述越粗则适应能力越广;层次越低则适应能力越差。
对象分析方法:
通过分析多个该对象的实例场景,以获取对象的多个侧面。通过归纳整理的方法抽象出对象的一般特征。
二、基础——在学习中思考
2.1.1 参与者
1. 基本概念
- 系统之外
- 与系统交互
- 某人或某事物
2. 找到参与者的思路
- 对系统有明确目标和要求并主动发出动作
- 系统为谁服务
- 不存在没有参与者的用例,用例不应该自动启动,也不应该主动启动另一个用例
2.1.2 用例
用例是把现实世界的需求捕获下来的方法。
1. 用例的前置条件和后置条件
一个完整的用例由参与者、前置条件、场景、后置条件构成。
2. 用例的特征
- 独立——不需要与其他用例交互而独自完成参与者的目的。
- 有意义——用例的执行结果对参与者来说是可观测的和有意义的。(后台的监控进程对参与者来说是不可观测的,因此应该作为系统需求在补充规约中定义而不是一个用户需求)。
- 由参与者发起——没有不存在参与者的用例,用例不应该自动启动,也不应该主动启动另一个用例
- 用例必须以动宾短语形式出现——用例必须是一个动作和一个动作的受体。
2.1.3 分析类(边界类、控制类、实体类)
1. 边界类
- 用于对系统外部环境与其内部运作之间的交互进行建模的类。
- 参与者与用力之间应当建立边界类。
- 用例之间如果有交互,应当为其建立边界类(用例之间的访问要通过接口或者代理类来实现,不允许用例之间直接访问内部对象。)
- 用例与系统外的非人对象有交互(这通常是因为异构系统、异构书籍、访问权限等愿意。边界类可以演化为中介和通信协议)
2. 控制类
- 用于对一个或几个用例所特有的控制行为进行建模。
- 主要起到协调对象的作用——从边界类通过控制类访问实体类,或者实体类通过控制类访问另一个实体类。(原因:边界类直接控制实体类的模型类似于C/S结构,这种结果,业务层逻辑代码要么与显示混在一起,要么与数据逻辑混在一起)
- 控制类的实例通常控制其他对象,他将用例的特有行为进行封装。
- 控制类来源于对用例场景中行为的定义
- 在提取控制类时,要认真考察用例场景中的行为,如果行为在执行步骤、执行要求或者执行结果上具有类似的特征,应该考虑进行适当的抽象。
3. 实体类
实体类——用于对必须存储的信息和相关行为建模的类。
实体对象——用于保存和更新一些相关的有关信息,例如事件、人员或者一些现实生活中的对象
2.1.4 类
类用于定义对象,对象用于实现用例。
类的来源可是用例实现对系统多徐对象的需求,也可以是任何已开发的对象模型,即现有的系统模块、采用的软件框架、第三方产品等。
1. 属性
属性的对象的特征,表明了对象的唯一性。
属性名是一个名词,描述与对象有关的属性的角色。
只有对象单独具有的特征才能被建模为属性,否则应该使用类的关联关系或聚合关系对特征进行建模。
2. 方法
原则上,访问对象或影响其他对象的属性或关系的唯一途径就是方法
3. 可见性
- 公有——属性和方法对其他模型元素是可见的。这种应该少用,减少与其他模块的耦合度
- 保护——属性和方法只对类本身、他的子类或友元是可视的。
- 私有——属性和方法只对类本身或者友元可见
2.1.5 关系
1. 关联关系——association(表示方法 —— )
- 用一条直线表示,表示不同类的对象之间的关系。比如A和B之间互相引用才能实现交互,A和B之间建立的就是关联关系。
- 依赖关系通常表示两根实例之间的临时关联关系
单向关联关系 (表示方法 ——> )
- 用一条带箭头的直线表示。例如A->B,表示A“知道”B,但是B“不知道”A。例如用例中,单向关联关系用于链接参与者和用例,箭头由参与者指向用例,表示参与者“知道”用例的存在。
2. 依赖关系——dependency (表示方法 - - - - - - - > )
- 即A事物发生变化。B事物必须发生变化。我们称B依赖于A。反之,则无依赖关系。
- 依赖是一种特殊的关联关系。比如A保存了B对象的ID,但是A对象对B对象没有操作,这时A与B是关联关系;如果A使用了B对象的属性或方法,则B的修改会导致A的修改,这是A依赖于B
- 双向依赖是十分不好的结构,应该杜绝产生双向依赖关系的产生
3. 扩展关系 (表示方法 )
代表了多个用例的可复用部分。
4. 包含关系 (表示方法 )
用于用例模型,说明在实现基本用例的用例实例过程中插入的行为段。(类似于stl中,queue包含了deque)
5. 实现关系 realize (表示方法 A实现B )
用户在用例模型中连接用例和用例的实现,说明基本用例的一个实现方式
6. 精化关系 refine (表示方法 )
- 使用场景——用例模型
- 一个基本用力可以分解出许多更小的关键精化用例,这些精化用例更细致的展示了基本用例的核心业务
7. 泛化关系 generalization (表示方式 )
用于说明两个对象之间的继承关系
8. 聚合 aggregation (表示方法 )
表示对象之间的关系,表达整体由部分构成的语义。例如大雁群和大雁
9. 组合 composition (表示方法)
表示实体和对象之间的关系,表达整体拥有部分的语义。例如母公司拥有许多子公司
2.1.6 组件
系统中实际存在的可更换部分,他实现特定的功能,符号一套接口标准并实现一组接口。
组件代表系统中的一部分物理设施,包括软件代码或其他等价物
一个类可能被分派给多个组件以完成该组件的功能,当组件被编译或打包成--个物理文件时,每个组件都拥有这个类的一个拷贝或者引用该类的途径。
2.1.6.1 组件的特性
1. 完备性
组件包含一些类和接口,一个组件应当能够完成一项或一组特定的业务目标(或说功能)。从调用者的观点看,它不需要调用多个组件来完成一-个业务请求。
例如我们将组件A定义为用户注册,那么我们应该在组件A中包含所有实现用户注册的必需的类和接口,在任何时候,仅通过组件A就可以注册-一个用户而无须访问组件外的其他类。
2. 独立性
独立性是说,组件应当是可以独立部署的,与其他组件无依赖关系,最多仅保持关联关系。
3. 逻辑性
组件是从软件构件设计的观点来定义的,并非从需求中可以直接导出。组件建立在系统分析和设计的基础上, 对已经实现的功能进行逻辑划分。
组件的定义是为了规划系统结构,将一个复杂的系统分解为一个个具有完备功能的,可独立部署的小模块。这些小模这些小模块可大可小,从理论上说,可任意选择一部分功能定义一个组件。
4. 透明性
组件的修改应当只涉及组件的定义以及组件中所包含的类的重新指定,而不应当导致类的修改。
2.1.6.2 组件的使用
以下情况适合使用组件:
1. 分布式应用
在分布式应用的情况下,系统的功能可能被部署在异构环境下,一”个业务目标可能需要经历两个甚至多个节点才能完成。这时我们需要将实现业务目标的那些类和接口规划成一些组件,每个组件完成这个业务目标中的一-部分功能。这些组件可被独立部署在不同的节点上,相互之间通过既定的通信协议交互来完成业务目标
2. 应用集成
在应用集成项目中,经常面临新业务和遗留系统问题。新业务需要调用遗留系统的功能,但是又不能修改遗留系统。原因可能是修改遗留系统的代价高昂,也可能是结构差异导致新旧系统无法直接通信。
为了保证遗留系统能够被集成到新系统中,一个解决方案就是在新系统中规划出--些组件,这些组件所拥有的接口完成遗留系统的功能。新系统是的其他业务模块与这些组件交互,而这些组件则拥有遗留系统的代码或者通过某种方式(代理模式、适配置器等)使用遗留系统
3. 第三方系统
如果在建设的项目中,有第三方系统要访问本系统,出于松耦合的考虑,可以将本系统要提供给第三方系统使用的功能定义成一系列组件,让第三方通过组件来访问本系统。
在这些组件中,除了包含本系统的实现类外,还可以根据实际情况通过提供这些实现类的代理、适配器、消息中间件等手段来解耦第三方系统对本系统的依赖
三、UML核心视图
3.1 用例图
用例视图采用参与者和用例作为基本元素,以不同的视角展现系统的功能性需求。用例视图是了解系统的第一个关口,人们通过用例视图得知一个系统将会做什么。
一 般来说,有以下用例视图
3.1.1 业务用例视图——给客户看
业务用例视图使用业务主角和业务用例展现业务建模的结果。
业务主角视角
- 从业务主角视角来展示业务主角在业务中使用哪些业务用例来达成业务目标。
- 这个视角有利于向业务主角确认其业务目标是否都已经齐全,以此来检查是否有遗漏的业务用例没有发现。
业务模块视角
- 从业务模块视角来展示业务领域的业务目标,将参与了达成这一业务目标的业务主角与业务用例展现在这个视图中。
- 这个视角有利于从业务的完整性角度出发,检查完成某个业务的所有业务主角和业务用例是否已经齐全,以此来检查是否有遗漏的业务用例没有发现。
3.1.2 概念视图——给程序员看
- 概念用例视图用于展现从业务用例中经过分析分解出来的关键概念用例,并表示概念用例和业务用例之间的关系。
- 一般来说这些关系有扩展、包含和精化。
- 对于概念用例视图来说,一般是以业务用例为单元展现的,即将视图名称命名为业务用例名称,如果某几个业务用例关系紧密也可以放在-一个视图里展示。
3.1.3 系统用例视图
- 系统用例视图展现系统范围,将对业务用例进行分析后得到的系统用例展现出来。
3.2 类图
用于展示系统中的类以及相互关系。
类图是现实世界问题领域抽象对象的结构化、概念化、逻辑化描述。
3.2.1 概念层类图
- 这个层次的类图描述的是现实世界中问题领域的概念理解,类图中表达的类与现实世界的问题领域有着明显的对应关系,类之间的关系也与问题领域中实际事物的关系有着明显的对应关系。
- 概念层类图中的类和类关系与最终的实现类并不一定有直接和明显的对应关系。
- 在概念层上,类图着重于对问题领域的概念化理解,而不是实现,因此类名称通常都是问题领域中实际事物的名称。
- 概念层的类图是独立于实现语言和实现方式的。
图4.7展示了网上购物的业务实体图,这个类图表达了概念层的类观点。
说明在问题领域中,网上购物主要由商品、定单、支付卡这几个关键类构成,这几个类的交互能够完成网.上购物这个业务目标。
3.2.2 说明层类图
此层考察的是类的接口而不是实现。
3.2.3 实现层类图
实现层的类图大概是用得最普遍的,许多人在建模的时候根本没有概念层和说明层的类图而直接跳到实现层类图。原因不是他们确认对问题领域已经足够了解,并且设计经验十分丰富,而通常是不知道类图还有三个层次的观点。
实现层类图位于设计阶段。在这个阶段,类图可视为伪代码。甚至可以用工具直接将实现层类图生成可执行代码。
3.3 活动图
活动图描述了为了完成某一个目标需要做的活动以及这些活动的执行顺序。UML中有两个层面的活动图,一.种用于描述用例场景,另一种用于描述对象交互。
在使用活动图时,要随时保持清醒的头脑,活动图只是我们用来描述业务目标的达成过程并借此来发现对象的工具,它不是我们的分析目标,也不是编程的依据,
它只是对象的应用场景之一。
我们使用活动图来描述用例场景,帮助我们认识问题领域,从问题领域中发现关键的对象,然后就应该把活动图中的流程忘掉,而专心研究
关键对象的特性。最后,再来验证一下这些关键对象的某个交互结果是否的确能够达到用例场景所描述的业务目标。
3.3.1 用例活动图
3.3.2 对象活动图
3.3.3 泳道图
3.4 状态图
- 状态图显示一个状态机。
- 状态机用于对系统行为中受事件驱动的方面进行建模。
- 通常使用状态图来说明业务角色或业务实体可能的状态、导致状态转换的事件和状态转换引起的操作。
- 对于类的对象所有可能的状态,状态图显示它可能接收的消息、将执行的操作和在此之后类的对象所处的状态。
- 状态机用于描述实体类对象的整个生命周期内的状态变迁以获得对这个实体对象的理解,同时获得系统和实体对象相互影响的关系。
- 状态图通常只用于描述单个对象的行为,如果要描述对象间的交互,最好采用时序图或协作图。
3.5 时序图——用于描述按时间顺序排列的对象之间的交互模型
时序图描述了在参与交互的对象中所发生的事件,以及这些对象如何通过相互发送消息进行通信。
3.5.1 业务模型时序图
常用的uml元素
- ■ 对象
表示参与交互的对象。
- ■ 生命周期线
生命周期线表示对象的存在,当对象被激活(创建或者被引用)时,生命周期线上出现会话,表示对象参与了这个会话。
- ■ 消息
消息由一个对象的生命周期线指向另一个对象的生命周期线。如果消息指到空白的生命周期线,将创建-一个新的会话:如果消息指到已有的会话,表示该对象延续已有会话。.
消息的不同类型
- 一> 为简单消息,仅表示一个交互。
- < - - - 为返回消息,返回消息为源消息的返回体,而非新的消息。
- 为同步消息,同步消息表示发出消息的对象将停止所有后续动作一直等到接收消息方响应。同步消息
- 将阻塞源消息对象的所有行为。
- 为限时消息,限时消息是同步消息的一种特殊情况。源消息对象发出消息后将等待响应一段时间,在限定时间内还没有响应时,源消息对象将取消阻塞状态而执行后续操作
- 为异步消息。异步消息一般需要消息中间件的支持,如JMS、MQ等。
3.5.2 概念模型时序图
概念阶段的时序图采用分析类来绘制,目标同样是实现业务用例。但是,由于分析类本身代表了系统原型,所以这个阶段的时序图已经带有计算机理解。