UML类图在面向对象程序设计用来描述类之间关系的一个工具,本文以PlantUML 为例介绍UML基本语法1,演示代码使用C++
PlantUML基本结构
@startuml
在这里写uml具体内容
@enduml
申报要素
各种类型(类,抽象类,接口…)等表示 ,统一格式是 类型 类型名
@startuml
abstract abstract
abstract class "abstract class"
annotation annotation
circle circle
() circle_short_form
class class
diamond diamond
<> diamond_short_form
entity entity
enum enum
interface interface
protocol protocol
struct struct
@enduml
类型中成员的表示
添加成员
添加成员第一种方式,单个添加,格式 类名: 成员
成员包括字段和方法,在成员名称后加(参数列表)
表示的是方法,不加 ()
就是属性
class Person {
public:
void f1();
protected:
void f2(int);
private:
int m_age;
string m_name;
};
使用UML表示
@startuml
title Person类
class Person
Person : int f1()
Person : void f2(int)
Person : int m_age
Person : string m_name
@enduml
其中 title
标签是标题
第二种方法是在类声明的时候将成员一起声明
@startuml
title Person类
class Person {
int f1()
void f2(int)
int m_age
string m_name
}
@enduml
显示的UML和第一种方法一样
访问权限
当你定义属性或者方法时,你可以使用特殊符号定义相应条目的可访问性质。在 plantUML在对应的成员前面加上表示相应权限的字符就可以了
将 Person
类的表示加上访问权限
@startuml
title Person类
class Person {
+int f1()
#void f2(int)
-int m_age
-string m_name
}
@enduml
类间关系
在描述类间关系23之前先区分接口和抽象类4,C++ 没有定义区分这两者的关键字,只要类中有纯虚函数的统称为抽象类。我们根据类中的的成员进行一下区分:
接口,类中没有成员属性,只有方法且方法都是纯虚函数:
/*an interface declaration*/
class InterfaceClass {
public:
// declaring a pure virtual method by assigning 0
virtual void method_first() = 0 ;
virtual void method_second() = 0;
};
抽象类,至少有一个纯虚方法,可以有其他实现的方法和成员属性
/*Declaring an abstract class*/
class AbstractClass{
public:
AbstractClass(int attribute): m_attribute(attribute){}
virtual void method_first() = 0; // a pure virtual method
virtual void method_second(){ // implemented virtual method
// ...
}
private:
int m_attribute;
};
PlantUML 常用的关系图标表示
-
用
..
代替--
则实线变为虚线 -
..
、--
是垂直方向的线条,.
、-
是水平方向的线条 -
<|(|>)
、*
、o
可以出现在线条的两侧,或是同时出现 -
>
、<
表示的是箭头
实现关系
实现关系是指接口及其实现类之间的关系。
代码示例
class InterfaceClass {
virtual void f1() = 0;
};
class InterfaceImpl {
InterfaceImpl();
void f1() override {
//..
}
//others
};
在UML类图中,实现关系用空心三角和虚线组成的箭头来表示,从实现类指向接口。PlantUML用 ..|>
或 <|..
表示,两者只是箭头指向不同,或者使用 class [实现类类名] implements [接口名]
@startuml
title 实现关系
interface InterfaceClass {
+virtual void f1() = 0
}
class InterfaceImpl {
+InterfaceImpl()
+void f1() override
}
' class InterfaceImpl implements InterfaceClass
InterfaceClass <|.. InterfaceImpl
@enduml
' class InterfaceImpl implements InterfaceClass
是被注释的语句,它和下一句是一样的意思
泛化关系
泛化关系(Generalization)是指对象与对象之间的继承关系。如果对象A和对象B之间的“is-a”关系成立,那么二者之间就存在继承关系,对象B是父对象,对象A是子对象。例如,一个年薪制员工“is a”员工,很显然年薪制员工Salary对象和员工Employee对象之间存在继承关系,Employee对象是父对象,Salary对象是子对象。
class Employee {
// 不是抽象类
};
class Professor: public Employee {
};
在UML类图中,泛化关系用空心三角和实线组成的箭头表示,从子类指向父类。PlantUML 用 <|--
或 --|>
或者使用 class [子类名称] extends [基类名称]
@startuml
title 泛化关系
class Employee
class Professor extends Employee
' class Professor <|-- Employee
@enduml
关联关系
关联关系(Association)是指对象和对象之间的连接,它使一个对象知道另一个对象的属性和方法,即一个类中的字段包含另一个类类型。关联关系有单向关联和双向关联。如果两个对象都知道(即可以调用)对方的公共属性和操作,那么二者就是双向关联。如果只有一个对象知道(即可以调用)另一个对象的公共属性和操作,那么就是单向关联。
class TimeCard;
class Employee {
private:
Timecard m_timecard;
}
关联关系描述不同类的对象之间的结构关系;它是一种静态关系, 通常与运行状态无关,一般由常识等因素决定的;它一般用来定义对象之间静态的、天然的结构; 所以,关联关系是一种“强关联”的关系;比如,乘车人和车票之间就是一种关联关系;学生和学校就是一种关联关系;
在UML图中,双向关联关系用带双箭头的实线或者无箭头的实线双线表示。单向关联用一个带箭头的实线表示,箭头指向被关联的对象。
@startuml
title 关联关系
class TimeCard
class Employee
Employee -> TimeCard
@enduml
依赖关系
依赖关系,他描述一个对象在运行期间会用到另一个对象的关系。与关联关系不同的是,它是一种临时性的关系,通常在运行期间产生,并且随着运行时的变化; 依赖关系也可能发生变化;
class Pen;
class Student{
public:
void write(Pen p) { }
};
在UML类图中,依赖关系用一个带虚线的箭头表示,由使用方指向被使用方。
@startuml
title 依赖关系
class Pen
class Student{
+void write(Pen p)
}
Student .> Pen
@enduml
聚合关系
聚合关系用于表示实体对象之间的关系,表示整体由部分构成的语义;例如一个部门由多个员工组成;
与组合关系不同的是,整体和部分不是强依赖的,即使整体不存在了,部分仍然存在;例如, 部门撤销了,人员不会消失,他们依然存在;在C++语言中同样是以类类型的成员体现
在UML图中,聚合关系用空心菱形加实线表示,空心菱形在整体一方,如下图表示A聚合到B上,或者说B由A组成;
@startuml
title 聚合关系
class A
class B
B o- A
@enduml
组合关系
与聚合关系一样,组合关系同样表示整体由部分构成的语义;比如公司由多个部门组成;
但组合关系是一种强依赖的特殊聚合关系,如果整体不存在了,则部分也不存在了;例如, 公司不存在了,部门也将不存在了;UML中组合关系用一条带实心菱形箭头直线表示
@startuml
title 组合关系
class Company
class BusinessUnit
Company *- BusinessUnit
@enduml
关系标签
在关系之间使用标签来说明时, 使用 :
后接 标签文字。
对元素的说明,你可以在每一边使用 ""
来说明.
@startuml
title 组合关系
class Company
class BusinessUnit
Company "1" *- "n" BusinessUnit : 包含
@enduml
参考
-
PlantUML语法参考: https://plantuml.com/zh/class-diagram ↩︎
-
类间关系:https://design-patterns.readthedocs.io/zh_CN/latest/read_uml.html ↩︎
-
抽象类和接口类区别: https://zhuanlan.zhihu.com/p/109655171 ↩︎