和大多数朋友一样,Jeffrey 在一开始的时候也十分的厌烦软件工程的一系列东西,对工程化工具十分厌恶,觉得它繁琐,需要记忆很多没有意思的东西。
但是之所以,肯定有是因为。对工程化工具的不理解和不认可主要是基于两个逻辑点:1)对于当下的任务来说,学习成本高,但是收效比较小,即收益小 2)即使学习了,利用空间不足,即应用少
如果要给出能说服自己学习软件工程的原因【也是一开始说服我自己的原因】
1)逐渐接触更大体积的代码,尤其是从零开始接触整体中的一部分业务代码,类的命名方式和方法变量的命名和自己习惯不同等等,导致理解成本高,花费的时间成本高,这个时候软件工程可以派上大用场降低理解成本
2)很多前辈和跟我们说,代码要先想好再写,因为这样可以从全局概览的角度去思考算法和数据存储方式。说的好,但是实现比较难,这个时候,就可以通过一些软件工程工具形象化的整理系统结构和算法步骤
1.换个角度
找了很多UML绘制的工具,但是发现这些工具会增加很大的学习成本,而且对于强迫症的我来说,每次画图都需要把线放的对齐笔直,性格原因又增加了我的使用成本,进而降低了我的使用效率,最终让我与一开始便利书写代码的初衷相违背,进而我选择了使用plantUML一种十分简单的符号语言的方式来绘制UML,学习成本低上手简单
2.UML 类图
使用类图的目的是为了形象化的得到系统中各个类/方法/接口/变量 之间的关系图
2.1类图中的基本元素
不要从学习图的角度去思考类图应该怎么画,从代码的角度出发去思考类图中应该有什么。
对于我的Java系统来说,从语法角度我需要在类图中体现类和它内部实例变量/方法,静态变量/方法,我还要体现类之间的继承和实现接口的关系,这些都应该是我的类图里面需要的。
那么作为一个类图的发明者来说,我就需要把这些东西都用符号表示出来。
首先表示一个类:Class animal,这个图我要把它的变量和方法分开,这样方便我去看:
对于我的变量来说,它有类型,对于我的方法来说,它有参数,有返回值,有返回值的类型和数据的类型,这些我都要体现出来
我的变量和方法还有访问修饰符的限制,这些我也得表示出来
但是一般情况下,取决于UML 的绘制工具不同,我们用简单的键盘符号来表示访问修饰符:
public | private | protected | default |
---|---|---|---|
+ | - | # | ~ |
最后有的时候我想把一些类归类,进而体现它的包,所以我需要把包也体现出来:
最后当然你可以通过手绘制的形式来画UML,而这里我们通过在idea 中plantUML插件的形式来完成,相信优秀的你肯定会插件的下载,就叫这个名,这时候你会发现你的idea 的右边的一列上有plantUml,点开它。
然后找个文件夹,new个txt文件,然后输入以下代码,你就能看到上图啦:
@startuml
package "Entity"{
class animal{
+isAlive: boolean
#gender: int
-age: int
~race: String
+breath(): void
}
class bird
class dog
class cat
}
@enduml
2.2类图中的关系元素 6个三组
这一块就一个字,麻烦!但是也不麻烦,用几个表,我们简单说明一下,这个地方需要一点点的耐心和记忆力。类类之间的关系从Java的角度来说是什么?继承,还有一种呢?对于接口的实现。
这是第一组:继承和实现,也是最好理解的一组
继承/泛化 | 实现 |
---|---|
一个类是另一个类的具体 | 一个类是另一个类的实现,实现要实现所有方法 |
空心实线箭头 | 空心虚线箭头 |
plantUml: 1)class bird extends animal 2)bird --|> animal | plantUml:bird …|> fly |
第二组:聚合和组合,需要注意两点:两个关系都代表部分和整体的关系,但是组合的程度更深,如果整体不存在,则部分也不存在,而聚合则是整体不存在,部分可以单独存在。比如:头和人就是组合关系,帽子和人就是聚合关系
组合 | 聚合 |
---|---|
部分指向整体,相同生命周期, | 部分指向整体,部分可以单独存在 |
实心菱形线 | 空心菱形线 |
plantUml:head --* bird | plantUml:hat --o bird |
第三组:关联和依赖关系
这两个是比较不容易区分的,但是通常来说关联关系就是一个类的一个实例变量是另一个类,而依赖关系是一个类的某个方法使用另一个类对象作为参数,但是这里要注意的是关联关系里面有双向关联,单向关联,自关联,多重性关联,怎么说?多重性关联就是,一对多,一对1 ,多对多,min对Max,当然其他的关系里面也可以这样表示
关联 | 依赖 |
---|---|
一个类的一个实例变量是另一个类 | 一个类的某个方法使用另一个类对象作为参数 |
实线实心箭头 | 虚线实心箭头 |
plantUml: 1)gender --> Student 2)workhouse “1” <–>“n” book | plantUml:空气 …>新陈代谢 |
以上的内容一定要牢记,多看几遍,记下来就好了
2.3补充语法
如果只有上面的这些内容,其实已经够我们去完成基本UML类图的绘制了,已经搭建起来了基本的类图和用plantUML语言来绘制类图的框架,但是,为了方便我们的使用,补充一部分plantUML语言的语法来使得绘制更加完善:
2.3.1 枚举类
enum Gender{
MALE,
FEMALE
}
2.3.2 关系上的注释/ 标签
Student --|> human : 继承
2.3.3 其他方式的注释
note left of Student : 这个学生不一般
note right of Student : 这个学生不二般
note top of Student : 这个学生不三般
note bottom of Student : 这个学生不四般
class Student{
+int gender
}
note left of Student::gender
这是性别
end note
2.3.4 标题
title
这是学生系统类图
end title
2.3.5 加粗/斜体
可以使用Markdown 语法来实现一些文字的变化
title
__这是学生系统类图__
**类图使用2**
end title
但是plantuml 用的是一个只有基本功能的Creole 引擎
2.3.6 图注
caption 图1
3.上手实践
完成了上面的这部分,可以尝试根据图把下面这个图的代码写出来:
先写再看!
@startuml
Class 动物{
+有生命 : boolean
+繁衍() : void
+新陈代谢(空气,水) : void
}
' 关系上的标签
动物 ..> 水:依赖
动物 ..> 空气:依赖
class 鸟{
+翅膀
+下蛋()
}
鸟 --|> 动物:继承
鸟 "1" *-- "2" 翅膀:组合
鸟 ..> 翅膀: 依赖
interface 飞翔{
+飞()
}
class 大雁 {
+飞翔()
+下蛋()
}
大雁 --|> 鸟
大雁 ..|> 飞翔
class 鸭{
+下蛋()
}
鸭 --|> 鸟
class 企鹅{
+下蛋()
}
企鹅 --|> 鸟
企鹅 --> 气候
class 大雁群{
+人字飞()
+一字飞()
}
大雁群 o-- 大雁
唐老鸭 --|> 鸭
@enduml
本篇关键字:从设计者的角度,图的关系,上手实践