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图如下:
关系与代码 继承(Inheritance) 1 2 public abstract class Employee {}public class Programmer extends Employee {}
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" ) } }
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) { } }
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 {}
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
类标记 一旦你定义了域或者方法,你可以定义 相应条目的可访问性质。
1 2 3 4 5 6 7 8 9 10 @startuml 20190904-mark-2 class Dummy { -field1 #field2 ~method1() +method2() } @enduml
通过修饰符{static}
或者{abstract}
,可以定义静态或者抽象的方法或者属性。
1 2 3 4 5 6 @startuml 20190904-mark-3 class Dummy { {static} String id {abstract} void methods() } @enduml
分割线
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
注释标记 备注和模板
模板通过类关键字(“<<”和”>>”)来定义
你可以使用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
可以在注释中使用部分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
设计模式的PLANTUML Adapter模式
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
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模式
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模式
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