时效性
本篇撰写时间为2021.11.9,由于计算机技术日新月异,博客中所有内容都有时效和版本限制,具体做法不一定总行得通,链接可能改动失效,各种软件的用法可能有修改。但是其中透露的思想往往是值得学习的。
Windows 10家庭中文版,版本20H2,操作系统内部版本19042.1288
UML
UML是Unified Modeling Language的简称
https://en.wikipedia.org/wiki/Unified_Modeling_Language
(可能需梯子)
The Unified Modeling Language (UML) is a general-purpose, developmental, modeling language in the field of software engineering that is intended to provide a standard way to visualize the design of a system.
In 1997, UML was adopted as a standard by the Object Management Group (OMG), and has been managed by this organization ever since. In 2005, UML was also published by the International Organization for Standardization (ISO) as an approved ISO standard. Since then the standard has been periodically revised to cover the latest revision of UML. In software engineering, most practitioners do not use UML, but instead produce informal hand drawn diagrams; these diagrams, however, often include elements from UML.
可以理解为OMG(Object Management Group)是一个致力于标准化的联合体,ISO(International Organization for Standarization, 国际标准化组织)是更大的标准化组织。UML是一种标准,被OMG adopt,然后又被ISO approve了。
软件工程师即使不画完全标准的UML图,也会在草图中体现相关元素。一些书籍(如著名的Head First Design Patterns)也会采用正式或不正式的UML帮助读者理解。
时效性:UML目前最新版本如图所示
UML类图
UML图有许多种,分别适用于不同的软件开发场景。
本篇中我们主要关注UML类图。
https://en.wikipedia.org/wiki/Class_diagram
(可能需梯子)
In software engineering, a class diagram in the Unified Modeling Language (UML) is a type of static structure diagram that describes the structure of a system by showing the system's classes, their attributes, operations (or methods), and the relationships among objects.
The class diagram is the main building block of object-oriented modeling.
UML类图的规范节选(详细完全的版本可以参见维基或者一些知乎文章等等)
- 类被包括三部分的“盒子”表示,顶部是类名,中间是attribute,底部是operation.
- 类继承关系用表示
...
该图就表示Student
继承Person
,具有public属性grades
,其类型为list
,等等。
UML绘图语言——PlantUML
简介
http://www.plantuml.com/plantuml/uml/SyfFKj2rKt3CoKnELR1Io4ZDoSa70000
该网址是UML绘图语言——PlantUML的在线服务器。可以敲纯文本的代码绘制UML图。
时效性:PlantUML版本V1.2021.13
例如
@startuml
!theme spacelab
Bob -> Alice : hello
@enduml
可以画出(以spacelab
为主题)的简单的Sequence Diagram
绘制类图
http://plantuml.com/guide
在该pdf教程中,搜索class diagram,很容易翻到该章节。
这是一些常见的element画法示例,该pdf下面还有一些relation画法示例,等等。
一个典型示例
其代码
@startuml
abstract Animal{
+alive
+metabolism(x: O2, y: Water)
+reproduce()
}
note "This is a note." as n0
Animal .. n0
abstract Bird{
+feather
+lay()
}
Animal <|-- Bird
class Wing
Bird "1"*-->"2" Wing
note on link: Composition
class Duck{
+lay()
}
Bird <|-- Duck
class WildGoose{
+flyInLine()
}
Bird <|-- WildGoose
class WildGooseFlock{
+flyInLine()
}
WildGooseFlock o-->WildGoose
note on link: Aggregation
interface Fly{
{abstract}+fly()
}
Fly <|..WildGoose
note on link: Implementation
class Penguin{
+lay()
}
Bird <|-- Penguin
class Climate
Climate <-- Penguin
note on link: Association
class DonaldDuck{
+speak()
}
Duck <|-- DonaldDuck
note on link: Inheritance
HaveATalk ()-- DonaldDuck
note on link: Lollipop interface
class Oxygen
Oxygen <.. Animal
class Water
Water <.. Animal
note on link: Dependence
@enduml
基本元素
abstract
,class
,interface
是常见的三种基本构成元素。- 默认情况,属性用不带括号来表示(
+alive
),方法用带括号表示(+speak()
)。+
,#
等标记public
等等。
- 默认情况,属性用不带括号来表示(
- 代码中的
note "mock" as n0
和note on link
是常见的添加注释的方式。
组合、聚合关系
https://en.wikipedia.org/wiki/Class_diagram 中用一句话概括
(可能需梯子)
Thus the aggregation relationship is often "catalog" containment to distinguish it from composition's "physical" containment.
- 组合表示“物理组成部分”,“有机整体”,比如心脏之于人。组合往往共享生命周期。
- 聚合表示“数据库关系”,“编目录”,比如学生之于班级。解散班级不代表杀死所有学生。
本例子中的组合关系:
@startuml
abstract Bird{
+feather
+lay()
}
class Wing
Bird "1"*-->"2" Wing
note on link: Composition
@enduml
其中2表示一只鸟有2只翅膀,1表示一只翅膀属于1只鸟。
本例子中的聚合关系:略。
接口和实现
- 接口跟抽象类有类似之处,都是要求继承它的类实现一些指定的抽象方法。但抽象类里可能有普通的方法(“功能性代码”),接口里不允许有。
- 接口可以用矩形表示法表示。即:
@startuml
class WildGoose{
+flyInLine()
}
interface Fly{
{abstract}+fly()
}
Fly <|..WildGoose
note on link: Implementation
@enduml
这跟一般的类继承基本类似。容易记忆语法。
- 也可以用棒棒糖(Lollipop)表示法表示,即:
@startuml
class DonaldDuck{
+speak()
}
HaveATalk ()-- DonaldDuck
note on link: Lollipop interface
@enduml
这种表示方法比较简略,即不再显式画出接口对应的矩形,而是用一个圆圈(旁注接口名)简单表示。实现了接口的类必须实现指定的方法(如speak()
,而这些方法名在矩形表示法中应当画在接口对应矩形里的)。
请特别注意区分接口名HaveATalk
和方法名speak()
是两个不同的概念,以及它们的联系。
其它关系
- Inheritance继承:一者更广泛,一者更具体。子类的对象一定是基类的对象。
- Dependence依赖:动物依赖于氧气和水,进行新陈代谢。
- Association关联:企鹅的分布、栖居、迁徙和气候有关联。
- 此处并不是双向关联,因为说“气候和企鹅有关联”多多少少有一点勉强(弱)。
总结与问答练习
- Q: 对于
WildGoose
和WildGooseFlock
的link,可以用什么样的数字(cardinality)标示比较恰当?
A:
@startuml
class WildGoose
class WildGooseFlock
WildGooseFlock "1" o--> "1..*" WildGoose
@enduml
当然,你也可以把1..*
改成m..*
,按照你个人认为的标准,可以取m
为2,3或10...合理即可。
- Q: 前述图中的棒棒糖表示法(Lollipop)等价于怎样的矩形表示法?
A:
@startuml
class DonaldDuck
interface HaveATalk{
{abstract} +speak()
}
HaveATalk <|.. DonaldDuck
@enduml
- Q: 书和书页更像是聚合还是组合关系?
A: 组合。如果你认为是聚合,那么你理解的销毁书应当是把书拆成单独的页。这显然不太符合一般人的理解了。 - Q: PlantUML的语法和语义分别是什么?
A: 语法:略。
语义:PlantUML的语义本质上就是UML的语义,具体到本篇中的类图就是类间关系等等。对于UML(当然以及PlantUML),我们最关心的就是其语义。