10 分钟学会 UML 类图

291 阅读7分钟

简要概述

UMLUnified Modeling Language )统一建模语言,用于软件系统分析和设计的语言工具,帮助开发人员进行思考和记录思路的结果。

在 UML 图中大致又分为 结构图行为图

  • 结构图:类图、对象图、包图、组件图、部署图、轮廓图
  • 行为图:交互图(序列图、时序图与协作图)、状态图、活动图等

类图 是使用频率最高的 UML 图之一,是描述 类与类之间的关系 的,类之间的关系包括:

  • 依赖
  • 泛化(继承)
  • 实现
  • 关联
  • 聚合
  • 组合

下面会根据这几种关系结合实例去概述。

一张图带你了解 UML 类图

在 UML 类图中,一般包含类名、属性和方法且带有分隔线分隔。

image-20220521220045691
  • 属性的表示形式

❝ 可见性 名称 : 类型 [=缺省值]

  • 方法的表示形式

❝ 可见性 方法名 [参数名 : 参数类型] : 返回值类型,无返回值时,其类型为 void

  • 接口的 UML 表示
image-20220521220045691

接口的表示形式与类类似,区别在于接口名须以 尖括号 包裹,或者以 斜体 形式表示,这里我更喜欢后一种表示方式来表示一个接口或抽象类。

依赖(Dependency)

依赖是一种偶然的、较弱的 使用 关系,如果 在类中用到了对方,那么我们就认为他们存在依赖关系。

image-20220521224226894
  • 作为方法的接收参数
public class Driver {
    public void drive(Car car) {}
}
  • 类的成员属性使用
public class Driver {
    private Car car;
    public void drive() {}
}
  • 作为方法的返回类型使用
public class Driver {
    public void drive() {}

    private Car getCar() {
        return car;
    }
}
  • 方法中创建实例使用
public class Driver {
    public void drive() {
        Car car = new Car();
    }
}
  • 调用静态方法使用
public class Driver {
    public void drive() {
        Car.mover();
    }
}

泛化(Generalization)

泛化关系实际上就是 继承关系,它是依赖关系的特例,用带空心三角形(指向父类)的实线表示,子类中 不需要标明其从父类继承下来的属性和方法,只须注明其新增的属性和方法即可。

image-20220521223722785

实现(Realization)

实现关系也是依赖关系的特例。用带空心三角形的虚线表示,同时类中须 需要列出接口中所声明的所有方法(这一点与类间的继承关系有所不同)。

image-20220521233806010

❝ 注意 Animal 为斜体,表示一个接口。

关联(Association)

关联关系表示类与类之间的联系,它是 依赖关系的特例 ,通常将一个类的对象作为另一个类的成员变量。在 UML 类图中,用实线连接有关联关系的类,可在关联线上标注角色名或关系名。 关联关系具有导航性。

  • 双向关联

双向关联用带双箭头的 实线 表示,也可用不带箭头的 实线 表示。如一个 Person 对应一个 IDCard , 同时一个 IDCard 对应一个 Person

image-20220521223357655

从上图可看出,双向关联的类的实例,互相持有对方的实例。

public class Person {
    private IDCard card;
}

public class IDCard {
	private Person person;
}
  • 单向关联

单向关联用带箭头的 实线 表示,一方持有另一方的实例。

image-20220521224004785
public class Person {
    private IDCard card;
}

public class IDCard {
}
  • 自关联

自关联是指属性类型为该类本身。例如在链表中,每个节点持有下一个节点的实例。

image-20220521224516466
  • 多重性关联

关联关系具有多重性(Multiplicity),表示两个对象在数量上的对应关系。在UML类图中,对象间的多重性可在关联线上用一个数字或数字范围表示。常见的多重性表示方式如下表所示。

表示方式多重性说明
1..1另一个类的一个对象只与该类的一个对象有关系,有且仅有一个
0..*另一个类的一个对象只与该类的零个或多个对象有关系,表示0个或多个
1..*另一个类的一个对象与该类的一个或多个对象有关系,至少 1 个
0..1另一个类的一个对象与该类的对象没关系或者只与该类的一个对象有关系,表示 0 个或 1个
m..n另一个类的一个对象与该类最少m,最多n个对象有关系,表示 m 到 n 个都可以*

例如一个网页可能没有可点击按钮,也可能有多个按钮,但是该页面中的一个按钮只属于该页面,其关联多重性如下图所示。

image-20220521215817456

聚合(Aggregation)

聚合关系表示的是整体与部分的关系,是 关联关系的特例。在聚合关系中,整体与部分 可以分离,且 部分对象可以脱离整体对象独立存在,整体对象并不控制部分对象的生命周期。

从代码实现上来讲,部分对象 不由整体对象创建,一般通过整体类的 带参构造器 或者 setter 方法或其它业务方法传入到整体对象,并且有整体对象以外的对象持有部分对象的引用。

image-20220521230707203
public class Computer {
    private Mouse mouse;

    public void setMouse(Mouse mouse) {
        this.mouse = mouse;
    }
}

public class Mouse {
}

❝ 具有导向性,Mouse 聚合到 Computer 中。

组合(Composition)

组合关系也表示整体和部分的关系,但是 整体与部分 不可以分离,在组合关系中,整体对象控制成员对象的生命周期,一旦整体对象不存在了,成员对象也即随之消亡。

从代码实现上看,一般在整体类的 构造方法中直接实例化成员类,并且除整体类对象外,其它类的对象无法获取该对象的引用。

image-20220521233242253
public class Person {
    private Head head;
    
    public Person() {
        head = new Head();
    }
}

public class Head {
}

❝ 具有导向性,Head 组合到 Person 中。

聚合关系与组合关系都表示整体与部分的关系,有何区别?

聚合关系中,部分对象的生命周期独立于整体对象的生命周期,或者整体对象消亡后部分对象仍然可以独立存在,同时在代码中一般通过整体类的带参构造方法或Setter方法将部分类对象传入整体类的对象,UML中表示聚合关系的实线以空心菱形开始。

组合关系中,部分类对象的生命周期由整体对象控制,一旦整体对象消亡,部分类的对象随即消亡。代码中一般在整体类的构造方法内创建部分类的对象,UML中表示组合关系的实线以实心菱形开始。 同时在组合关系中,部分类的对象只属于某一个确定的整体类对象;而在聚合关系中,部分类对象可以属于一个或多个整体类对象。级联删除 也是组合的一种。

聚合关系、组合关系与关联关系有何区别和联系?

聚合关系、组合关系和关联关系实质上是对象间的关系(继承和实现是类与类和类与接口间的关系)。从语意上讲,关联关系中两种对象间一般是平等的,而聚合和组合则代表整体和部分间的关系。而聚合与组合的区别主要体现在实现上和生命周期的管理上。

依赖关系与关联关系的区别是?

依赖关系是较弱的关系,一般表现为在局部变量中使用被依赖类的对象、以被依赖类的对象作为方法参数以及使用被依赖类的静态方法。而关联关系是相对较强的关系,一般表现为一个类包含一个类型为另外一个类的属性。

参考资料:

UML(一) 类图详解

学会 UML 类图