UML类图

  • UML类图关系及介绍
  • 与Java代码的对应关系
  • PlantUML制作类图
  • 设计模式类图举例
PlantUML制图-概述

UML类图

UML类图 类图是一种静态的结构图,用于描述类与类之间的关联关系和类的属性。使用类图可以更好的理解代码的结构,简化对系统的理解。

组成

类主要包含3部分:类名、属性和方法。某些情况下,类的性质和包含的内部类也可以包含在里面。其中类名不可省略,其他部分可以省略。
并且正体类名表示可以被实例化,斜体表示这个类是抽象的。

属性的写法规范为:修饰符[描述信息]属性, 方法名[参数][: 返回类型]。 例如:
+doSomething(String name, int age) : void

其中修饰符,加号(+)表示public;减号(-)表示private;井号(#)表示protected;省略这些修饰符表示具有package(包)级别的可见性。

如果属性或方法具有下划线,则说明它是静态的。描述信息使用 << 开头,使用 >> 结尾。类的性质是由一个属性、一个赋值方法和一个取值方法组成。书写方式和方法类似。

对应Java中的一个包。

接口

接口是一系列操作的集合, 对应Java中的一个接口类型,UML中有两种表述方式: 1. 类似于类的方式;2.棒棒糖方式(适合接口中仅有一个方法)

关系

常见的关系有: 继承(Inheritance),关联关系(Association),聚合关系(Aggregation),组合关系(Composition),依赖关系(Dependency),实现关系(Realization/Implementation)。

聚合和符合属于关联关系(Association),一般关系表现为继承或实现关系(is a),关联关系表现为变量(has a ),依赖关系表现为函数中的参数(use a)。

UML图如下:
20190904-uml-1.png

关系与代码

继承(Inheritance)

1
2
public abstract class Employee{}
public class Programmer extends Employee{}

20190904-inheritance.png

1
2
3
4
5
6
7
8
9
10
@startuml 20190904-inheritance
!define Class(name,desc) class name as "name\ndesc"
namespace default{
Class(Programmer, 程序员) {
}
abstract Class(Employee, 员工) {
}
Employee <|-- Programmer : 泛化(继承)
}
@enduml

实现(Realization/Implementation)

1
2
3
4
5
6
7
8
9
public abstract interface Code{ 
void code();
}
public class Programmer interface Code{
@Override
public void code(){
System.out.println("coding")
}
}

20190904-implementation.png

1
2
3
4
5
6
7
8
9
10
11
@startuml 20190904-implementation
!define Class(name,desc) class name as "name\ndesc"
!define Interface(name,desc) interface name as "name\ndesc"
namespace default{
Class(Programmer, 程序员) {
}
Interface(Code, 编码技能) {
}
Code <|.. Programmer : 实现
}
@enduml

依赖(Dependency)

1
2
3
4
5
6
7
8
9
public class Keyboard{

}

public class Programmer{
public void code(Keyboard keyboard){

}
}

20190904-dependency.png

1
2
3
4
5
6
7
8
9
10
11
12
@startuml 20190904-dependency
!define Class(name,desc) class name as "name\ndesc"
!define Interface(name,desc) interface name as "name\ndesc"
namespace default{
Class(Programmer, 程序员) {
+code(Keyboard keyboard) : void
}
Class(Keyboard, 键盘) {
}
Keyboard <.. Programmer : 实现
}
@enduml

关联(Association),组合(Composition),聚合(Aggregation)

关联,组合,聚合 三者Java上无区别, 仅仅是概念上的差别

  • 关联:A类有B类有逻辑上的连接,例如:学生-课程, 学生选课, 课被学生选;
  • 组合:A类拥有一个B类, 例如:汽车-引擎, 引擎是汽车的组成部分;
  • 聚合:A类有一个B类,例如:公司-员工, 公司内包含员工;
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
public class Student{
private List<Course> courses;
}

public class Course{
private List<Student> students;
}

public class Car{
private Engine engine;
private List<Tyre> tyres;
}

public class Engine{

}

public class Tyre{

}

public class Company{
private List<Employee> employeies;
}

public class Employee{

}

20190904-association-composition-aggregation.png

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
@startuml 20190904-association-composition-aggregation
!define Class(name,desc) class name as "name\ndesc"
!define Interface(name,desc) interface name as "name\ndesc"

namespace association{
Class(Student, 学生) {
-List<Course> courses
}
Class(Course, 课程) {
-List<Student> students(非必需包含本属性)
}
Student "n" --> "n" Course : 关联
}
namespace composition{
Class(Car, 汽车) {
-Engine engine
-List<Tyre> tyres
}
Class(Engine, 引擎) {
}
Class(Tyre, 轮胎) {
}
Car "1" *--> "1" Engine : 一对一组合
Car "1" *--> "n" Tyre : 一对多组合
}
namespace aggregation{
Class(Company, 公司) {
-List<Employee> employee
}
Class(Employee, 员工) {
}
Company "1" o--> "n" Employee : 聚合
}
@enduml

其他绘图

关系标记

在标签的开始或结束位置添加< 或 >以表明是哪个对象作用到哪个对象上。

1
2
3
4
5
6
7
8
9
10
@startuml 20190904-mark-1
class Car
class Wheel
class Person
class Driver

Driver - Car : drives >
Car *- Wheel : have 4 >
Car -- Person : < owns
@enduml

20190904-mark-1.png

类标记

一旦你定义了域或者方法,你可以定义 相应条目的可访问性质。

1
2
3
4
5
6
7
8
9
10
@startuml 20190904-mark-2

class Dummy {
-field1
#field2
~method1()
+method2()
}

@enduml

20190904-mark-2.png

通过修饰符{static}或者{abstract},可以定义静态或者抽象的方法或者属性。

1
2
3
4
5
6
@startuml 20190904-mark-3
class Dummy {
{static} String id
{abstract} void methods()
}
@enduml

20190904-mark-3.png

分割线

plantuml 默认会使用实线分割类名,成员,方法。同时也支持自定义分割线

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
@startuml 20190904-mark-4
class Foo1 {
You can use
several lines
..
as you want
and group
==
things together.
__
You can have as many groups
as you want
--
End of class
}

class User {
.. Simple Getter ..
+ getName()
+ getAddress()
.. Some setter ..
+ setName()
__ private data __
int age
-- encrypted --
String password
}
@enduml

20190904-mark-4.png

注释标记

备注和模板

模板通过类关键字(“<<”和”>>”)来定义

你可以使用note left of , note right of , note top of , note bottom of这些关键字来添加备注。

你还可以在类的声明末尾使用note left, note right,note top, note bottom来添加备注。

此外,单独用note这个关键字也是可以的,使用..符号可以作出一条连接它与其它对象的虚线。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
@startuml 20190904-mark-6
class Object << general >>
Object <|--- ArrayList

note top of Object : In java, every class\nextends this one.

note "This is a floating note" as N1
note "This note is connected\nto several objects." as N2
Object .. N2
N2 .. ArrayList

class Foo
note left: On last defined class

@enduml

20190904-mark-5.png

可以在注释中使用部分html标签:

  • <b> 加粗
  • <u> 下划线
  • <i> 斜体
  • <s> 删除线
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
@startuml 20190904-mark-6

class Foo
note left: On last defined class

note top of Object
In java,<u>class</u>
<b>extends</b>
<i>this</i> one.
end note

note as N1
This note is <u>also</u>
<s>words</s> lines
And this is hosted by
end note

@enduml

20190904-mark-6.png

设计模式的PLANTUML

Adapter模式

20190904-uml-2.png

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
@startuml 20190904-uml-2

class Client {

}

interface Adapter {
+operation()
}

class ConcreteAdapter {
-adapteee
+operation()
}

class Adaptee {
+adaptedOperation()
}

note "对象适配器模式" as N1

Client -right-> Adapter
Adapter <|-down- ConcreteAdapter
Adaptee <-right- ConcreteAdapter
N1 -right- ConcreteAdapter

@enduml

20190904-uml-3.png

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
@startuml 20190904-uml-3

class Client {

}

interface Adapter {
+operation()
}

class ConcreteAdapter {
+operation()
}

class Adaptee {
+adaptedOperation()
}

note "类适配器模式" as N1

Client -right-> Adapter
Adapter <|-down- ConcreteAdapter
Adaptee <|-left- ConcreteAdapter
N1 -right- ConcreteAdapter

@enduml

Builder模式

20190904-uml-4.png

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
@startuml 20190904-uml-4
class Director {
-pbuilder : Builder *
+constuct() : Product*
+setBuilder(Builder*) : void
}

class Builder {
+ builderPartA() : void
+ builderPartB() : void
+ builderPartC() : void
+ getResult() : void
}

class ConcreteBuilder {
+ builderPartA() : void
+ builderPartB() : void
+ builderPartC() : void
}

class Product {

}

note as N1
pbuilder->builderPartA();
pbuilder->builderPartB();
pbuilder->builderPartC();
pbuilder->getResult();
end note

Director o-right- Builder
Director -- N1
Builder <|.down. ConcreteBuilder
ConcreteBuilder .right.> Product

@enduml

Strategy模式

20190904-uml-5.png

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
@startuml 20190904-uml-5
class Context {
-Strategy strategy
+doSomething() : void
+setStrategy(Strategy*) : void
}

interface Strategy {
+execute() : void
}

class StrategyA {
+execute() : void
}

class StrategyB {
+execute() : void
}

Context *-right- Strategy
Strategy <-up- StrategyA
Strategy <-up- StrategyB

@enduml