当前位置: 首页 > news >正文

用PlantUML和语雀画UML类图

概述

首先阐述一下几个简单概念:

  • UML:是统一建模语言(Unified Modeling Language)的缩写,它是一种用于软件工程的标准化建模语言,旨在提供一种通用的方式来可视化软件系统的结构、行为和交互。UML由Grady Booch、Ivar Jacobson和James Rumbaugh三位软件工程专家在1990年代初共同开发,并在1997年被对象管理组织(Object Management Group, OMG)正式采纳。
  • PlantUML:是一个开源工具,它允许我们用文本形式来描绘和创建UML图。在VSCode中可以安装扩展来绘制,而在语雀的MarkDown编辑器中,则可以用“文本绘图”形式直接在文档中创建。
  • UML类图:在面向对象语言或开发中类图是最基础也最有用的一种图,它可以描述类的成员以及多个类之间的关系。

在Godot中,我们使用GDScript进行游戏或类库开发时,也需要涉及面向对象开发和类图等,用于清晰表达自己的思路或详实自己的文档。

因为语雀文档内部创建更方便,所以本文主要介绍在语雀中绘制UML类图的方式。

在语雀中创建PlantUML类图

在语雀文档中,在任意一行行首输入“/wbht”,可以找到“文本绘图”,回车即可插入“文本绘图”的Block。
image.png
默认插入的“文本绘图”块如下:
image.png
点击顶部的“模板”,在下拉列表中选择“类图”:
image.png
会自动填充和渲染一个如下的类图:
image.png
我们便可以在这个基础上进行UML类图的绘制。

PlantUML类图基础语法

起止标记

首先是起止标记,绘图描述的内容必须包裹在一对@startuml@enduml标记之间。

@startuml@enduml

申明元素

@startuml@enduml标记之间,我们可以使用特定的语法来申明类图的元素。PlantUML本身支持很多种元素申明,详见:类图的语法和功能
但在GDScript中最常用到的便是类和枚举,其他的元素类型并不支持。

@startuml
class a
enum skills
@enduml

其中:

  • class为关键字,后面跟类名,可以声明一个类;
  • enum为关键字,后面跟枚举名,可以声明一个枚举;

上面代码生成的类图如下:
在这里插入图片描述

添加类或枚举的成员

以类为例,我们可以使用:(注意前后都有一个空格)来为申明的类添加成员,名称不带()的被视为是属性,带()的被视为是方法。

@startuml
class a
a : name
a : sex
a : age
a : say_hello()
@enduml

上面的代码生成的类图如下:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-1zKGwWHp-1720151404747)(https://i-blog.csdnimg.cn/direct/e94e04d6b32e4fe0ada960213df64dba.png)]

也可以用花括号语法:

@startuml
class a{namesexagesay_hello()
}
@enduml

这样的写法更接近于真实代码的形式,可以省去重复的类名和:

申明成员类型

可以为类的成员申明数据类型。

@startuml
class a{String namebool sexint agevoid say_hello()
}
@enduml

可以采用C风格的前置类型声明:
在这里插入图片描述

也可以采用类似GDScript的冒号后置类型申明形式:

@startuml
class a{name:String sex:boolage:intsay_hello():void
}
@enduml

在这里插入图片描述

设定成员的可访问性

类图可以更具体的标记属性和方法的可访问性,也就是private、protected、public,如果是C++之类的或许可以用上,但是在GDScript中并不涉及这部分。
下面是具体的修饰符和意义。

字符图标(属性)图标(方法)可访问性
-private 私有
#protected 受保护
~package private 包内可见
+public 公有

下面是一个简单的例子:

@startuml
class a{+name:String -sex:bool~age:int+say_hello():void
}
@enduml

绘制效果如下:

在这里插入图片描述

表示静态变量或方法

Godot3.x就支持静态函数,Godot4.x更是支持了静态变量。
在PlantUML类图中我们可以精确的表示静态函数和静态变量成员,以与非静态成员区分。
方法也很简单就是在静态成员之前添加{static}修饰符。

@startuml
class a{+ {static} name:String -sex:bool~age:int+{static}say_hello():void
}
@enduml

绘制效果如下:
在这里插入图片描述

可以看到静态成员的名称下添加了下划线。

使用分隔线对成员进行自定义分组

可以在成员之间用--..==__进行自定义分割线的绘制

@startuml
class a{ame:String --sex:bool==age:int..say_hello():void__say_yes():void
}
@enduml

实际效果如下:
在这里插入图片描述

可以看到:

  • --是一条比较粗的横线,__是一条比较细的横线
  • ==是双横线
  • ..是虚线

你也可以在分割线基础上进行分组的命名。

@startuml
class a{ame:String -- 性别  --sex:bool== 年龄 ==age:int.. 方法 ..say_hello():void__ 还是方法 __say_yes():void
}
@enduml

绘制效果如下:
在这里插入图片描述

这样我们可以将成员进行分组,让类的结构更清晰易懂。

多个类之间的关系表示

关系类型符号绘图
泛化关系<|–
组合关系*–
聚合关系o–
  • --代表实线,可以用..替代表示虚线。
  • <|*o分别代表箭头的类型

类与类之间的关系可以查阅相关的视频或文档,这里不做赘述,这里只举例说明继承关系的表示。

@startuml
Car <|-- Bus
@enduml

这里我们直接省略class关键字,申明了CarBus两个类,并且使用<|--连接它们。
生成的类图如下:
在这里插入图片描述

它的含义就是,Car作为父类,Bus作为子类,Bus继承自Car

  • 新手注意:继承关系的箭头是由子类指向父类。

我们可以继续这个例子,添加Car的其他子类型:

@startuml
Car <|-- Bus
Car <|-- motorcycle
Car <|-- bicycle
@enduml

生成类图如下:
在这里插入图片描述

在箭头连线上添加文本

可以在整个箭头连线关系的最后,在:后面添加文本信息,用于显示在连线上。

@startuml
Car <|-- Bus:继承自
Car <|-- motorcycle:继承自
Car <|-- bicycle:继承自
@enduml

生成类图如下:
在这里插入图片描述

表示类之间的数量关系

也可以用双引号,在连线的起始端和末尾端添加文本,用于表示类似ER(实体关系图)中的“一对一”、“一对多”、“多对多”等关系。
在继承关系中可能使用这种描述不太恰当,可以在“组合”或“聚合”等关系中使用。
下面的代码表示,一个汽车有4个轮子组成:

@startuml
汽车 "1" *-- "4" 轮子:组成
@enduml

生成类图如下:
在这里插入图片描述

控制类绘制的位置

在连线之间可以使用updownleftright关键字来手动控制类的绘制位置。
以之前的Car派生的例子为例:

@startuml
Car <|-- Bus:继承自
Car <|-- motorcycle:继承自
Car <|-- bicycle:继承自
@enduml

默认绘制为:
在这里插入图片描述

通过在表示实线的--之间,指定上下左右方位的关键字:

@startuml
Car <|-left- Bus:继承自
Car <|-up- motorcycle:继承自
Car <|-right- bicycle:继承自
@enduml

就可以将类图渲染为如下形式:
在这里插入图片描述

绘制备注

note关键字用于绘制备注。
可以使用note 位置 of 元素的形式,为类、枚举或者其他类图元素设定备注。

@startuml
Car <|-left- Bus:继承自
Car <|-up- motorcycle:继承自
Car <|-right- bicycle:继承自note bottom of Car:车,基类
note bottom of Bus:公共汽车
note bottom of bicycle:自行车
note left of motorcycle:摩托车
@enduml

绘制效果如下:
在这里插入图片描述

还有一种写法,可以省略of 元素,但是需要紧跟在class申明之后,或者指定两个类的关系之后。

@startuml
class Car
note bottom:车,基类Car <|-left- Bus:继承自
note bottom:公共汽车Car <|-up- motorcycle:继承自
note left:摩托车Car <|-right- bicycle:继承自
note bottom:自行车
@enduml

绘制效果如下:
在这里插入图片描述

可以看到效果基本上无异。
还可以用note "备注内容" as 变量形式将备注申明为一个类似单独元素的东西。
再使用--..进行连接:

@startuml
class Car
note "车,基类" as N1
Car -- N1
@enduml

效果如下:
在这里插入图片描述

另外,在备注中,可以使用\n进行多行文本的换行控制。

为类图添加标题

使用title关键字可以为类图添加标题。

@startuml
title 车类的继承关系类图
Car <|-left- Bus:继承自
Car <|-up- motorcycle:继承自
Car <|-right- bicycle:继承自note bottom of Car:车,基类
note bottom of Bus:公共汽车
note bottom of bicycle:自行车
note left of motorcycle:摩托车
@enduml

绘制效果如下:
在这里插入图片描述

为类图添加页脚

如果你不喜欢顶部的标题,可以使用footer关键字指定一个底部的页脚。

@startumlCar <|-left- Bus:继承自
Car <|-up- motorcycle:继承自
Car <|-right- bicycle:继承自note bottom of Car:车,基类
note bottom of Bus:公共汽车
note bottom of bicycle:自行车
note left of motorcycle:摩托车
footer 车类的继承关系类图
@enduml

绘制效果如下:
在这里插入图片描述

Godot中的一些类图实例

上面我们已经学习了如何用PlantUML进行类图的绘制。下面就举一些Godot中的例子。

子类与父类(继承关系)

@startumlControl <|-- Button
note bottom:泛化关系(继承关系)\n子类指向父类,\n实线空心三角箭头@enduml

绘图效果:
在这里插入图片描述

成员引用(一般关联关系)

@startumlclass class01{attr:class02
}class01 --> class02
note bottom:单向关联关系\n引用者指向被引用者class class03{attr:class04
}class class04{attr:class03
}class03 -- class04
note bottom:双向关联关系\n箭头消失class class05{sub_itm:class05
}class05 --> class05
note bottom:自关联关系\n自己的成员变量引用自己@enduml

绘制效果:
在这里插入图片描述

部分与整体(聚合与组合)

@startumlclass Player {
}
note left:玩家
Player -up-|> CharacterBody2D
Player o-- CollisionShape2D
note bottom:碰撞形状
Player o-- Sprite
note bottom:玩家长相
@enduml

绘制效果:
在这里插入图片描述

更复杂的可以有:

@startuml
title Godot中2D角色的节点组成结构(2class Player {
}
note left:玩家
Player -up-|> CharacterBody2D
Player o-- CollisionShape2D
note bottom:碰撞形状
Shape2D <-down- CollisionShape2D
Player o-- HitBox
note bottom:攻击判定区域
HitBox -up-|> Area2D
CollisionShape2D2 -down-o HitBox
Shape2D <-down- CollisionShape2D2Player o-- Sprite
note bottom:玩家长相
@enduml

在这里插入图片描述

组合关系

@startuml
title Godot中的组合关系
class Tree {
}Tree *-- TreeItem
note right:组合关系,\n父类由子类组成,\n父类消失,子类失去意义,\n子类消失,父类无法构成。@enduml

在这里插入图片描述

依赖关系

@startuml
title Godot中类的依赖关系
class ShapePoints {
+static rect():PackedVector2Array
}class myCanvas{
+ draw_rect():void
}ShapePoints <.. myCanvas
note right: 依赖关系:\n一个类用**局部变量**\n**方法参数**或者\n**对静态方法的调用**\n来访问另一个类@enduml

在这里插入图片描述

总结

本文带领Godot使用者,学习和使用基础的PlantUML类图绘制技巧。
希望对Godoter们编写和设计自己的类以及类库有所帮助,你也可以用来绘制和讲解设计模式等。
本文不详之处,可以查阅其他大佬的文章或翻找PlantUML官方文档。
若有错误之处,还请指正。

相关文章:

用PlantUML和语雀画UML类图

概述 首先阐述一下几个简单概念&#xff1a; UML&#xff1a;是统一建模语言&#xff08;Unified Modeling Language&#xff09;的缩写&#xff0c;它是一种用于软件工程的标准化建模语言&#xff0c;旨在提供一种通用的方式来可视化软件系统的结构、行为和交互。UML由Grady…...

uniapp微信小程序电子签名

先上效果图&#xff0c;不满意可以直接关闭这页签 新建成单独的组件&#xff0c;然后具体功能引入&#xff0c;具体功能点击签名按钮&#xff0c;把当前功能页面用样式隐藏掉&#xff0c;v-show和v-if也行&#xff0c;然后再把这个组件显示出来。 【签名-撤销】原理是之前绘画时…...

MetaPoint_速读

Meta-Point Learning and Refining for Category-Agnostic Pose Estimation https://arxiv.org/abs/2404.14808https://github.com/chenbys/metapointabstract 这篇文章介绍了一种名为Meta-Point Learning and Refining的框架&#xff0c;用于实现类别不可知的姿势估计。该框…...

数据库逆向工程工具reverse_sql

reverse_sql 是一个用于解析和转换 MySQL 二进制日志&#xff08;binlog&#xff09;的工具。它可以将二进制日志文件中记录的数据库更改操作&#xff08;如插入、更新、删除&#xff09;转换为反向的 SQL 语句&#xff0c;以便对系统或人为产生的误操作进行数据回滚和恢复。 *…...

四大内网穿透利器对比

本文精选四款市场上的佼佼者——巴比达、花生壳、Frp及NatApp&#xff0c;详细剖析它们的特点与优势&#xff0c;助力企业和个人用户精准选择&#xff0c;其中特别强调了巴比达在企业级安全访问方面的突出贡献。 1. 巴比达 特点 深度安全防护&#xff1a;巴比达提供全方位安…...

【LeetCode】每日一题:跳跃游戏 II

给定一个长度为 n 的 0 索引整数数组 nums。初始位置为 nums[0]。 每个元素 nums[i] 表示从索引 i 向前跳转的最大长度。换句话说&#xff0c;如果你在 nums[i] 处&#xff0c;你可以跳转到任意 nums[i j] 处: 0 < j < nums[i] i j < n 返回到达 nums[n - 1] 的最小…...

SpringBoot拦截器

目录 一、拦截器快速入门 &#xff08;1&#xff09;什么是拦截器 &#xff08;2&#xff09;拦截器的使用步骤 1、定义拦截器 &#x1f340;preHandle() 方法 &#x1f340;postHandle() 方法 &#x1f340;afterCompletion() 方法 2、注册配置拦截器 二、拦截器详解…...

uniapp中实现跳转链接到游览器(安卓-h5)

uniapp中实现跳转链接到游览器&#xff08;安卓-h5&#xff09; 项目中需要做到跳转到外部链接&#xff0c;网上找了很多都不是很符合自己的要求&#xff0c;需要编译成app后是跳转到游览器打开链接&#xff0c;编译成web是在新窗口打开链接。实现的代码如下&#xff1a; 效果&…...

WPF UI 界面布局 魔术棒 文字笔记识别 技能提升 布局功能扩展与自定义 继承Panel的对象,测量与排列 系列七

应用开发第一步 功能分类&#xff1a;页面上的功能区域划分。。。。需求分析 业务逻辑 数据流 功能模块 UI/UX 编码 测试 发布 功能开发与布局 不用显式的方式设定元素的尺寸 不使用屏幕坐标来指定位置 Grid 功能最强大&#xff0c;布局最灵活的容器…...

文件格式是.pb应该怎么查看?

文件格式为.pb的文件&#xff0c;通常是Google Protocol Buffers&#xff08;简称PB&#xff09;序列化后的二进制文件。要查看.pb文件的内容&#xff0c;可以采用以下方法&#xff1a; 1. **直接打开&#xff08;不推荐&#xff09;**&#xff1a; - 直接打开.pb文件通常会显示…...

android2024 gradle8 Processor和ksp两种编译时注解实现

android编译时注解&#xff0c;老生常谈&#xff0c;外面的例子都是bindView&#xff0c;脑壳看疼了&#xff0c;自己学习和编写下。 而且现在已经进化到kotlin2.0&#xff0c;google也逐渐放弃kapt&#xff0c;进入维护状态。所以要好好看看本贴。 参考我的工程&#xff1a; h…...

elementui的table的@selection-change阻止事件改变

说明&#xff1a; 最近有个不想说的&#xff08;xxx&#xff09;业务&#xff0c;在表格勾选每一行的时候要触发一系列查询功能&#xff0c;查询失败还要把那个勾勾回退。真实蛋疼&#xff01;表格勾选的默认selection-change是change事件&#xff0c;一般change事件是在完成之…...

空间数据采集与管理:为什么选择ArcGISPro和Python?

你还在为找不到合适的数据而苦恼吗&#xff1f;你还在面对大量数据束手无策&#xff0c;不知如何处理吗&#xff1f;对于从事生产和科研的人员来说&#xff0c;空间数据的采集与管理是地理信息系统&#xff08;GIS&#xff09;和空间分析领域的关键环节。通过准确高效地采集和管…...

案例精选 | 聚铭综合日志分析系统为江苏省电子口岸构建高效安全的贸易生态

江苏省电子口岸有限公司&#xff0c;成立于2009年&#xff0c;由江苏省贸促会携手南京海关、江苏检验检疫局及江苏海事局等部门共同出资组建。公司承载着推动江苏乃至长三角地区国际贸易便利化的重大使命&#xff0c;致力于打造一个集先进性、创新性、高效性于一体的电子口岸综…...

TCP粘包

目录 TCP粘包产生的原因 TCP粘包的现象 TCP粘包的解决方案 TCP粘包是指在TCP通信中,发送方发送的多个数据包在接收方被错误地合并成一个数据包的现象。tcp粘包在发送端和接收端都有可能发生。发送端粘包:发送端需要等缓冲区满才发送出去,造成粘包。接收方粘包:接收方不及…...

数据泄露态势(2024年5月)

监控说明&#xff1a;以下数据由零零信安0.zone安全开源情报系统提供&#xff0c;该系统监控范围包括约10万个明网、深网、暗网、匿名社交社群威胁源。在进行抽样事件分析时&#xff0c;涉及到我国的数据不会选取任何政府、安全与公共事务的事件进行分析。如遇到影响较大的伪造…...

二手闲置平台小程序的设计

管理员账户功能包括&#xff1a;系统首页&#xff0c;个人中心&#xff0c;用户管理&#xff0c;卖家管理&#xff0c;商品分类管理&#xff0c;商品信息管理&#xff0c;商品购买管理&#xff0c;商品配送管理 微信端账号功能包括&#xff1a;系统首页&#xff0c;商品信息&a…...

协程libgo的使用

c开源协程库libgo介绍及使用-CSDN博客 libgo库的github地址&#xff1a;GitHub - yyzybb537/libgo: Go-style concurrency in C11 使用libgo编写并行程序&#xff0c;即可以像golang一样开发迅速且逻辑简洁&#xff0c;又有C原生的性能优势。它的特点有&#xff1a; 1.提供go…...

什么叫低频晶振?低频晶振最低频率能达到多少?低频晶振封装尺寸有哪些?

低频晶振指的是那些工作在较低频率范围内的晶体振荡器&#xff0c;通常这类振荡器的标称频率低于8MHz。这些晶振在各种电子设备中都有应用&#xff0c;尤其是在那些需要精确但不需要高频振荡的应用场景中&#xff0c;比如实时时钟(RTC)、低速串行通信接口(如UART、IC等)、以及一…...

Splunk Enterprise 任意文件读取漏洞(CVE-2024-36991)

文章目录 前言漏洞描述影响版本漏洞复现POC批量检测-nuclei脚本 修复建议 前言 Splunk Enterprise 是一款强大的机器数据管理和分析平台&#xff0c;能够实时收集、索引、搜索、分析和可视化来自各种数据源的日志和数据&#xff0c;帮助企业提升运营效率、增强安全性和优化业务…...

ESP32 I2S音频总线学习笔记(四): INMP441采集音频并实时播放

简介 前面两期文章我们介绍了I2S的读取和写入&#xff0c;一个是通过INMP441麦克风模块采集音频&#xff0c;一个是通过PCM5102A模块播放音频&#xff0c;那如果我们将两者结合起来&#xff0c;将麦克风采集到的音频通过PCM5102A播放&#xff0c;是不是就可以做一个扩音器了呢…...

2025 后端自学UNIAPP【项目实战:旅游项目】6、我的收藏页面

代码框架视图 1、先添加一个获取收藏景点的列表请求 【在文件my_api.js文件中添加】 // 引入公共的请求封装 import http from ./my_http.js// 登录接口&#xff08;适配服务端返回 Token&#xff09; export const login async (code, avatar) > {const res await http…...

Linux离线(zip方式)安装docker

目录 基础信息操作系统信息docker信息 安装实例安装步骤示例 遇到的问题问题1&#xff1a;修改默认工作路径启动失败问题2 找不到对应组 基础信息 操作系统信息 OS版本&#xff1a;CentOS 7 64位 内核版本&#xff1a;3.10.0 相关命令&#xff1a; uname -rcat /etc/os-rele…...

【从零学习JVM|第三篇】类的生命周期(高频面试题)

前言&#xff1a; 在Java编程中&#xff0c;类的生命周期是指类从被加载到内存中开始&#xff0c;到被卸载出内存为止的整个过程。了解类的生命周期对于理解Java程序的运行机制以及性能优化非常重要。本文会深入探寻类的生命周期&#xff0c;让读者对此有深刻印象。 目录 ​…...

【JVM】Java虚拟机(二)——垃圾回收

目录 一、如何判断对象可以回收 &#xff08;一&#xff09;引用计数法 &#xff08;二&#xff09;可达性分析算法 二、垃圾回收算法 &#xff08;一&#xff09;标记清除 &#xff08;二&#xff09;标记整理 &#xff08;三&#xff09;复制 &#xff08;四&#xff…...

GO协程(Goroutine)问题总结

在使用Go语言来编写代码时&#xff0c;遇到的一些问题总结一下 [参考文档]&#xff1a;https://www.topgoer.com/%E5%B9%B6%E5%8F%91%E7%BC%96%E7%A8%8B/goroutine.html 1. main()函数默认的Goroutine 场景再现&#xff1a; 今天在看到这个教程的时候&#xff0c;在自己的电…...

FFmpeg:Windows系统小白安装及其使用

一、安装 1.访问官网 Download FFmpeg 2.点击版本目录 3.选择版本点击安装 注意这里选择的是【release buids】&#xff0c;注意左上角标题 例如我安装在目录 F:\FFmpeg 4.解压 5.添加环境变量 把你解压后的bin目录&#xff08;即exe所在文件夹&#xff09;加入系统变量…...

群晖NAS如何在虚拟机创建飞牛NAS

套件中心下载安装Virtual Machine Manager 创建虚拟机 配置虚拟机 飞牛官网下载 https://iso.liveupdate.fnnas.com/x86_64/trim/fnos-0.9.2-863.iso 群晖NAS如何在虚拟机创建飞牛NAS - 个人信息分享...

HubSpot推出与ChatGPT的深度集成引发兴奋与担忧

上周三&#xff0c;HubSpot宣布已构建与ChatGPT的深度集成&#xff0c;这一消息在HubSpot用户和营销技术观察者中引发了极大的兴奋&#xff0c;但同时也存在一些关于数据安全的担忧。 许多网络声音声称&#xff0c;这对SaaS应用程序和人工智能而言是一场范式转变。 但向任何技…...

认识CMake并使用CMake构建自己的第一个项目

1.CMake的作用和优势 跨平台支持&#xff1a;CMake支持多种操作系统和编译器&#xff0c;使用同一份构建配置可以在不同的环境中使用 简化配置&#xff1a;通过CMakeLists.txt文件&#xff0c;用户可以定义项目结构、依赖项、编译选项等&#xff0c;无需手动编写复杂的构建脚本…...