UML学习文档(二)

参考资料:

https://zhuanlan.zhihu.com/p/669466741

UMLChina《软件方法》

https://cloud.tencent.com

https://www.processon.com/knowledge/classdiagram

目录

5.C-分析

--软件设计的两种复用形式

核心域的复用

非核心域的复用

--分析类

三种构造型

一次交互回合

分析建议

--"彩色建模"思想的四种类

事物

描述

时段时刻

角色

--类图

类名

属性

语法

(1)可见性

(2)属性名称

(3)数据类型

(4)初始值

(5)属性字符串

属性是否直接描述类的特征

是否有复杂结构或1对多的属性

属性是否对类的所有对象都有意义

操作(或方法)

语法

(1)可见性

(2)操作名称

(3)参数表

(4)返回类型

(5)属性字符串

使用符号总结:

其他构成元素

类的职责

类的约束

--接口

--类间的关系

[泛化(is-a)- 空心三角箭头](#泛化(is-a)- 空心三角箭头)

识别泛化关系的方法

继承(Generalization/Inheritance)-实线+空心三角箭头

从特殊到一般

从一般到特殊

实现(Realization)-虚线+空心三角箭头

关联(has-a)-实线箭头

单向关联(Association)-实线箭头

双向关联(Association)-实线

自关联(Association)-实线箭头

聚合关联(Aggregation)-实线箭头+空心菱形箭头

组合关联(Composition)-实线箭头+实心菱形箭头

依赖-(use-a)-虚线箭头(Dependency)

类关系举例图(https://cloud.tencent.com/developer/article/2105150)

类关系总结图(https://www.processon.com/knowledge/classdiagram)

--绘制分析类图的步骤

--分析序列图

与业务序列图的对比

序列图元素

责任分配的交互原则

专家原则--资源决定消息内容

老板原则--由老板发送消息给我

可视原则--只发消息给朋友

--分析状态图

不同视角对类的描述

状态图元素

与活动图的对比

状态

历史状态

并发状态

入口动作和出口动作

迁移

结构

执行顺序

哪些类值得画状态图

画图要点

序列图的组成部分

角色(Actor)

对象(Object)

生命线(LifeLine)

激活(Activation)

消息(Message)

[同步消息(Synchronous Message)](#同步消息(Synchronous Message))

[异步消息(Asynchronous Message)](#异步消息(Asynchronous Message))

[返回消息(Return Message)](#返回消息(Return Message))

交互框

序列图的作用

确认和丰富逻辑表达

细化用例表达

描述类职责分配

绘制序列图的步骤


5.C-分析

--软件设计的两种复用形式

核心域的复用

真正涉及到业务的核心域知识,是复用的最重要领域。

但大部分软件研发人员,这一步往往都没有做好。

非核心域的复用

目前大多数软件组织的复用仅停留在基础设施领域的复用,即使有自己的"内部开发平台",也仅是根据自己所开发系统的需要对基础设施作进一步封装。

这种非核心域的复用,各个公司组织都大同小异,没有长久的竞争优势。

画分析类图的时候要拆分核心域与非核心域,避免过于复杂,互相干扰。

这里的类,可以理解为需求中涉及或接触到的系统对象。

--分析类

三种构造型

  1. 边界类:输入、输出,及简单的过滤;
  2. 控制类:控制用例流,为实体分配责任;
  3. 实体类:系统的核心,封装领域逻辑和数据。

一次交互回合

  • 执行者先把消息发给边界类对象,边界类对象能履行的就履行,无法履行的责任,再发给控制类对象。
  • 控制类对象就像总裁办,不做具体工作,只是将责任分解后分配给实体类对象。
  • 实体类按照它们之间的耦合程度聚集成若干聚合(也有可能一个类单独形成聚合)。
  • 控制类对象发送消息时,先发给聚合的整体对象(也称聚合根),再由聚合根分配给聚合内的其他对象。
  • 最后,由边界类对象反馈信息,完成一个交互回合。

分析建议

对于类的分析,和关系型数据库的表结构分析是类似的,得到的类和表也基本是一一对应的。

这里,建议按照领域模型来区分类,这样得到的类,是最符合领域的特性的,也一定是最契合业务发展的(业务本身就是在其领域的基础上做流程变化)。

--"彩色建模"思想的四种类

事物

其状态值得关注,在其身上发生领域事件。

描述

对象较少,封装某方面的规则,状态变化不值得关注。

时段时刻

对象多,属性不应修改。

角色

解耦事物与时段时刻。

这种建模的套路是:从"时段时刻"开始,找出后面的"角色"和"事物";

在"描述"的关系上找到"事物"。

--类图

类不能像一个过程,而应该是一个对象。(设计源于需求,高于需求)

类名

抽取用例规约中的名词和事件,使用名词短语为类命名。例如,"Customer"、"Order"等。注意:

  1. 命名以专业术语为准。
  2. 确保名称简洁,不要带冗余信息(不要加类、C、表、库、信息等词)。
  3. 类名应该准确清晰的反映出问题域中的概念。
  4. 名称中的每个词的首字母应大写。
  5. 使用正体名称来表示可实例化的类。
  6. 使用斜体名称表示抽象的类。
  7. 英文命名则用单数。
  8. 多处重复的同一概念,命名要一致(如顾客与客户)。

属性

列出类的关键特征或数据成员,包括数据类型。

属性通常放在类名的下方,属性名前不要加类名(冗余),格式为"属性名: 数据类型",例如,"name: String"。

语法

可见性\] 属性名称 \[:数据类型\] \[=初始值\] \[{属性字符串}

(1)可见性

可见性用于控制该属性被类的外部成员的可访问性。主要有以下四种情况:

  • +:公有属性,其它类可以访问该属性;
  • -:私有属性,不能被其它类访问(默认为私有);
  • #:保护属性,只能被本类及其派生类访问;
  • ~:包内可见,可以被本包中的其它类访问;
(2)属性名称

能够准确描述类特征的一个标识符,属性名通常是一个名词或名词短语。

一般单字属性使用小写字母,多字属性从第2个单词开始,每个单词的第一个字符要大写。

(3)数据类型

属性所属的数据类型,如布尔类型、整型、浮点型,也可以是用户自定义的类型。

(4)初始值

属性的默认值,在类的实例没有赋其它值时,将采用该值作为该属性的值。

(5)属性字符串

用来指定该属性的其它信息。任何希望进一步描述该属性又没有合适的地方时都可以放在此处。

以上关于属性的描述内容虽然很多,但一般属性的可见性和属性名称是必需的部分。

属性是否直接描述类的特征
是否有复杂结构或1对多的属性

如果属性再分解就得到其他领域的概念(如人的姓名,姓名再分解就是 string 类型,属于其他领域知识),那么这个属性可以留在类中。

如果可以继续分解成本领域的概念(比如人的组织,组织可继续分解),可以考虑把这个属性独立出去变成另一个类。

多重性大于一的属性,可以再分解出其他类,比如人可以有多个电话,那么电话可以是另一个类(联系方式)。

属性是否对类的所有对象都有意义

分析类属性时,不能完全照搬某张文件表单里的字段,他们不一定是一个领域的。

透过现象(非核心域的实现手段)看本质(核心域的机制、专业术语)。

属性要能直接用于描述类,在划分属性从属于哪个类时,试试"[类]的[属性]"能否说通。

操作(或方法)

列出类可执行的操作或函数,包括返回类型和参数列表。

方法一般位于属性的下方,格式为"方法名(参数): 返回类型"。

例如,"placeOrder(productID, quantity): Boolean"。

语法

可见性\] 操作名称 \[(参数表)\]\[:返回类型\]\[{属性字符串}

1 )可见性

与属性相同,规定该操作的可访问范围。

操作的可见性也是有+(公有)、-(私有),#(保护)和~(包内可见)四种。

2 )操作名称

用来描述所属类的行为的动词或动词短语。

在UML中,和属性名的表示类似,单字的操作名小写;

多字的操作名,除第一个单词外,其余单词的开头字母要大写。

3 )参数表
  • 参数表是一些按顺序排列的属性定义了操作的输入;
  • 参数表是可选的;
  • 参数的定义使用"名称:类型"的定义方式;
  • 如果存在多个参数,则将各个参数用逗号隔开;
  • 参数可以具有默认值,适用调用时没有提供参数值的情况。

如下面的time,其类型为Date,默认值为currentdate(即当前时间):

4 )返回类型

此项为可选项目,即操作不一定必须有返回类型。

但在具体编程语言中使用void关键字来代表这种无返回值的情况。

5 )属性字符串

任何在其它地方没有描述清楚的内容都可以在这里进行描述。

使用符号总结:

  • --: private
  • +: public
  • ~: default
  • #: protected
  • 下划线: static
  • 斜体: 抽象 (注意也可以用两个尖括号包裹来表示抽象,比如 ------ <<我是抽象类or接口>>)
  • 冒号前是方法名/变量名(根据有无括号区分),冒号后是返回参数/变量类型(根据有无括号区分),如果没有冒号的话表示方法返回空(也有人通过:void表示返空)

其他构成元素

在UML中,一个类通常由名称(Name)、属性(Attribute)和操作(Operation)构成。

除此之外,

类的构成还包含类的职责(Responsibility)、约束(Constraint)和注释(Note)等信息。

类的职责

在UML中,可以在操作部分的下面再添加一个区域,用来说明类的职责,即说明类或其它元素的契约或义务。

创建一个类时,同时声明这个类的所有对象具有相同种类的状态和相同种类的行为,在较高层次上,这些相应的属性和操作正是要完成类的职责和特性。职责可以使用一个短语、一个句子或一段短文的形式来描述。

类的约束

类的约束指定了该类所要满足的一个或多个规则,在UML中,约束使用一个大括号括起来的文本信息:

--接口

  • 接口是在没有给出对象的实现和状态的情况下对对象行为的描述;
  • 接口包含操作但不包含属性,且它没有对外界可见的关联;
  • 一个类可以实现一个或多个接口,从而支持接口所指定的操作;

接口可以使用下面两种形式来表示:

e.g IUser是一个接口,VipUser是一个类,VipUser类要实现接口IUser

--类间的关系

尽量基于静态关系来建立动态关系

泛化(is-a)- 空心三角箭头

泛化类似面向对象中的继承,子类通过继承超类而拥有超类的特征,是一种集合关系,比如,人与男人、女人。

注意警惕拼凑泛化。

识别泛化关系的方法
  • 对类与类之间,思考 A 是否是 B 的一种,而 B 是否是 A 的一种。
  • 对多个已有的类,抽象出公共部分,形成超类。
  • 从一般的类,细化出特殊的子类。
  • 尽量不要跨领域形成泛化关系。
继承(Generalization/Inheritance)-实线+空心三角箭头

从子类指向父类即表示一个继承。

从特殊到一般
从一般到特殊
实现(Realization)-虚线+空心三角箭头

从实例指向接口表示一个实现,从实例指向抽象类也表示一个实现。

关联(has-a)-实线箭头

对象通过组装其他对象而拥有其他对象的特征,是个体类间的关系,如人与手、脚。

只有系统负责维护的关系,才构成关联。

泛化和关联,可以视分析场景进行转变,可用于简化模型。

关联关系又可以分为单向关联、双向关联、自关联、聚合关联和组合关联5种情形。

关联的多重性:

多重性是UML中使用最广泛的约束,主要有以下几种形式:

|----------|--------|--------|-----------|
| 形式 | 含义 | 形式 | 含义 |
| 0 | 恰为0 | 0..n | 0到多个 |
| 1 | 恰为1 | 1..n | 1到多个 |
| 0..1 | 0或1 | 3..n | 3到多个,至少3个 |
| n | 0或多个 | 3,5,7 | 3个或5个或7个 |

单向关联(Association)-实线箭头

使用实线箭头表示,可以是单向或双向的。

双向关联(Association)-实线

双向关联关系不再绘制箭头,使用直线直接连接两个类即可,如下面两个类之间的关系即是双向关联关系:

自关联(Association)-实线箭头

自关联关系即一个类与自己进行关联。下面类关系的意思是employee类中有一个为employee类型的leader成员,表示员工的领导:

聚合关联(Aggregation)-实线箭头+空心菱形箭头

从整体指向局部即表示一个聚合。

多个对象和某个对象的关联紧密,视为受其影响的分区(如公司与各个部门)。

但他们的关联是相对较弱的,局部对象是可以脱离整体对象而单独存在的。

组合关联(Composition)-实线箭头+实心菱形箭头

从整体指向局部即表示一个组合,组合又叫合成。

比聚合更严格,"部分"对象跟随"整体"对象销毁而销毁;

"部分"对象只属于一个"整体"对象;

"整体"对象负责"部分"对象的创建与销毁。

依赖-(use-a)-虚线箭头(Dependency)

其他不能视为泛化或关联的类间关系。

从使用者指向被使用者,即一个物体需要通过另一个物体来完成工作,但他们之间没有包含的关系。

类关系举例图(https://cloud.tencent.com/developer/article/2105150

类关系总结图(https://www.processon.com/knowledge/classdiagram

--绘制分析类图的步骤

1,研究分析问题领域,确定系统的需求;

2,发现对象与对象类,明确他们的含义和责任,确定属性和操作。

3,发现类之间的静态联系;

4,设计类与联系;

5,绘制类图并编制相应的说明。

--分析序列图

与业务序列图的对比

序列图元素

  • 消息传入:类的操作--责任
  • 消息传出:类完成操作所需合作--协作
  • 位置:每个用例下面,对应用例的路径
  • 基本路径:一张图
  • 简单的扩展点:可以合并到基本路径图
  • 复杂扩展点:单独一张图,和基本路径图间链接
  • 控制类只分配责任

责任分配的交互原则

专家原则--资源决定消息内容

独立完成

分解大责任

委托给其他领域

老板原则--由老板发送消息给我

向聚合/组合结构所发的消息,先通过整体对象处理和中转

减少耦合,减少修改引起的波动

判定聚合/组合要谨慎!

可视原则--只发消息给朋友

--分析状态图

帮助定义恰当责任

不同视角对类的描述

状态图元素

与活动图的对比

状态

表现相同行为的属性值和链接的组合

历史状态

历史:记住最近一次离开时最后所处的子状态

 浅历史:仅记住同层

 深历史:记住最精确子状态

并发状态

从不同维度分割属性值组合,不同分区的状态并存(AND)

入口动作和出口动作

迁移

结构
执行顺序

哪些类值得画状态图

全方位考虑建模的可能性和必要性

核心类

 状态多事物(彩色建模)≈实体≈责任起点≈聚合的根

边界类

 有时代表的是整个系统的状态,有时不是

质量要求很高的系统→每个类

画图要点

  1. 从类名思考修饰词(形容词)
  2. 从行为思考状态变化
  3. 从状态属性思考状态名称
  4. 优先使用原生形容词,防止换汤不换药

序列图的组成部分

角色(Actor)

通常指外部与系统交互的实体,可以是人或其他系统。

对象(Object)

系统内部的实体,通常是指类的实例。在序列图中,对象通过一个矩形框表示,对象的命名方式有三种:

对象名和类名,例如:dispatcherServlet:DispatcherServlet

只显示类名,即表示它是一个匿名对象,例如::DispatcherServlet

只显示对象名不显示类名,例如:dispatcherServlet

生命线(LifeLine)

从对象框向下延伸的虚线,表示对象在时间线上的存在。生命线上的不同点表示不同的时间点。

激活(Activation)

通常在生命线上显示为一个较窄的矩形。它表示对象在一段时间内是活跃的,即正在响应或执行某个操作。

消息(Message)

对象之间交互的基本单位,表示为带箭头的线。消息可以是同步,异步,或返回消息。

同步消息(Synchronous Message)

发送者在发送消息后,必须等待接收者完成相应的操作后才能继续。

异步消息(Asynchronous Message)

发送者发送消息后,可以继续执行后续的操作,不需等待接收者。

返回消息(Return Message)

接收者完成操作后,将结果返回给发送者。

交互框

UML在2.0时在时序图中加入了交互框。

交互框用来解决交互执行的条件和方式,它允许在序列图中直接表示逻辑组件,用于通过指定条件或子进程的应用区域,为任何生命线的任何部分定义特殊条件和子进程。

组合片段共有13种,名称及含义如下:

|--------------|--------|-------------------------------------------------------------------------------------------------------------------------------------|
| 片段类型 | 名称 | 说明 |
| Opt | 选项 | 包含一个可能发生或可能不发生的序列。可以在临界中指定序列发生的条件。 |
| Alt | 抉择 | 包含一个片段列表,这些片段包含备选消息序列。在任何场合下只发生一个序列。可以在每个片段中设置一个临界来指示该片段可以运行的条件。else 的临界指示其他任何临界都不为 True 时应运行的片段。如果所有临界都为 False 并且没有 else,则不执行任何片段。 |
| Loop | 循环 | 片段重复一定次数。可以在临界中指示片段重复的条件。Loop 组合片段具有"Min"和"Max"属性,它们指示片段可以重复的最小和最大次数。默认值是无限制。 |
| Break | 中断 | 如果执行此片段,则放弃序列的其余部分。可以使用临界来指示发生中断的条件。 |
| Par | 并行处理 | 片段中的事件可以交错。 |
| Critical | 关键 | 用在 Par 或 Seq 片段中。指示此片段中的消息不得与其他消息交错。 |
| Seq | 弱顺序 | 有两个或更多操作数片段。涉及同一生命线的消息必须以片段的顺序发生。如果消息涉及的生命线不同,来自不同片段的消息可能会并行交错。 |
| Strict | 强顺序 | 有两个或更多操作数片段。这些片段必须按给定顺序发生。 |
| Consider | 考虑 | 指定此片段描述的消息列表。其他消息可发生在运行的系统中,但对此描述来说意义不大。在"Messages"属性中键入该列表。 |
| Ignore | 忽略 | 此片段未描述的消息列表。这些消息可发生在运行的系统中,但对此描述来说意义不大。在"Messages"属性中键入该列表。 |
| Assert | 断言 | 操作数片段指定唯一有效的序列。通常用在 Consider 或 Ignore 片段中。 |
| Neg | 否定 | 此片段中显示的序列不得发生。通常用在 Consider 或 Ignore 片段中。 |

序列图的作用

确认和丰富逻辑表达

用于确认和丰富一个使用语境的逻辑表达,如用例的一部分或控制流。

细化用例表达

将用例表达的需求转化为更正式层次的精细表达。

描述类职责分配

根据对象之间的交互关系来定义类的职责,构成特定的用例。

绘制序列图的步骤

  1. 划清边界,识别交互语境:确定绘制时序图的范围和背景。
  2. 梳理角色和对象:确定时序图中的角色和对象。
  3. 确定对象间的交互消息:明确对象之间的交互消息。
相关推荐
静心观复4 天前
drawio画java的uml的类图时,class和interface的区别是什么
java·uml·draw.io
weixin_4569042720 天前
数据库设计与UML图
数据库·uml
希赛网23 天前
软考软件设计师常考知识点:(一)计算机组成与体系结构
软考·uml·编程语言·计算机基础·软件设计师
rolt24 天前
[pdf、epub]320道《软件方法》强化自测题业务建模需求分析共279页(202509更新)
产品经理·ddd·架构师·uml·领域驱动设计
攻心的子乐1 个月前
软考 UML类图 泛化继承 实现 聚合 组合(最强) 依赖(最弱
uml
攻心的子乐1 个月前
软考 UML 用例图 extend扩展关系 include包含关系 泛化继承inherit关系
uml
「QT(C++)开发工程师」1 个月前
UML | 最好的类图设计工具结合CSDN天启呈现-领路架构师
数据库·uml·类视图
小鱼儿LY1 个月前
软考系统架构设计师之UML统一建模语言
系统架构·软考·uml·架构设计师
workflower2 个月前
GitHub宕机自救指南
测试用例·需求分析·uml·敏捷流程·结对编程