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

image-20230408131050162

类型中成员的表示

添加成员

添加成员第一种方式,单个添加,格式 类名: 成员 成员包括字段和方法,在成员名称后加(参数列表) 表示的是方法,不加 () 就是属性

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

image-20230408134637019

其中 title 标签是标题

第二种方法是在类声明的时候将成员一起声明

@startuml

title Person类

class Person {
    int f1()
    void f2(int)
    int m_age
    string m_name
}

@enduml

显示的UML和第一种方法一样

访问权限

当你定义属性或者方法时,你可以使用特殊符号定义相应条目的可访问性质。在 plantUML在对应的成员前面加上表示相应权限的字符就可以了

image-20230408135643674

Person 类的表示加上访问权限

@startuml

title Person类

class Person {
    +int f1()
    #void f2(int)
    -int m_age
    -string m_name
}

@enduml

image-20230408140002052

类间关系

在描述类间关系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 常用的关系图标表示

image-20230408151622406

  • .. 代替 -- 则实线变为虚线

  • ..-- 是垂直方向的线条, .- 是水平方向的线条

  • <|(|>)*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 是被注释的语句,它和下一句是一样的意思

image-20230408141946545

泛化关系

泛化关系(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

image-20230408143024517

关联关系

关联关系(Association)是指对象和对象之间的连接,它使一个对象知道另一个对象的属性和方法,即一个类中的字段包含另一个类类型。关联关系有单向关联和双向关联。如果两个对象都知道(即可以调用)对方的公共属性和操作,那么二者就是双向关联。如果只有一个对象知道(即可以调用)另一个对象的公共属性和操作,那么就是单向关联。

class TimeCard;
class Employee {
    
private:
    Timecard m_timecard;
}

关联关系描述不同类的对象之间的结构关系;它是一种静态关系, 通常与运行状态无关,一般由常识等因素决定的;它一般用来定义对象之间静态的、天然的结构; 所以,关联关系是一种“强关联”的关系;比如,乘车人和车票之间就是一种关联关系;学生和学校就是一种关联关系;

在UML图中,双向关联关系用带双箭头的实线或者无箭头的实线双线表示。单向关联用一个带箭头的实线表示,箭头指向被关联的对象

@startuml

title 关联关系

class TimeCard
class Employee 

Employee -> TimeCard

@enduml

image-20230408151231218

依赖关系

依赖关系,他描述一个对象在运行期间会用到另一个对象的关系。与关联关系不同的是,它是一种临时性的关系,通常在运行期间产生,并且随着运行时的变化; 依赖关系也可能发生变化;

class Pen;
class Student{
public:
    void write(Pen p) { }
};

在UML类图中,依赖关系用一个带虚线的箭头表示,由使用方指向被使用方。

@startuml

title  依赖关系

class Pen
class Student{
    +void write(Pen p)
}

Student .> Pen

@enduml

image-20230408151259233

聚合关系

聚合关系用于表示实体对象之间的关系,表示整体由部分构成的语义;例如一个部门由多个员工组成;

与组合关系不同的是,整体和部分不是强依赖的,即使整体不存在了,部分仍然存在;例如, 部门撤销了,人员不会消失,他们依然存在;在C++语言中同样是以类类型的成员体现

在UML图中,聚合关系用空心菱形加实线表示,空心菱形在整体一方,如下图表示A聚合到B上,或者说B由A组成;

@startuml

title  聚合关系

class A
class B

B o- A 

@enduml

image-20230408152227230

组合关系

与聚合关系一样,组合关系同样表示整体由部分构成的语义;比如公司由多个部门组成;

但组合关系是一种强依赖的特殊聚合关系,如果整体不存在了,则部分也不存在了;例如, 公司不存在了,部门也将不存在了;UML中组合关系用一条带实心菱形箭头直线表示

@startuml

title   组合关系

class Company
class BusinessUnit

Company *- BusinessUnit

@enduml

image-20230408152850429

关系标签

在关系之间使用标签来说明时, 使用 :后接 标签文字。

对元素的说明,你可以在每一边使用 "" 来说明.

@startuml

title   组合关系

class Company
class BusinessUnit

Company "1" *- "n" BusinessUnit : 包含

@enduml

image-20230408153128262

参考


  1. PlantUML语法参考: https://plantuml.com/zh/class-diagram  ↩︎

  2. 类间关系: https://zhuanlan.zhihu.com/p/513024592  ↩︎

  3. 类间关系:https://design-patterns.readthedocs.io/zh_CN/latest/read_uml.html ↩︎

  4. 抽象类和接口类区别: https://zhuanlan.zhihu.com/p/109655171  ↩︎