UML类图

UML

UML(Unified Modeling Language,统一建模语言)是一种为面向对象系统的产品进行说明、可视化和编制文档的一种标准语言,是非专利的第三代建模和规约语言。UML是面向对象设计的建模工具,独立于任何具体程序设计语言。

UML和设计模式

设计模式(Design pattern)是一套被反复使用、多数人知晓的、经过分类编目的、代码设计经验的总结。个人觉得设计模式是前人大佬总结的一种思想,是一种脱离语言并且能够指导程序员更容易写出好的代码的编程习惯。对于一个没有太多经验的程序员,如何写出 简洁优雅,可复用性高,可扩展性强,高内聚低耦合 的代码至关重要。学习别人的设计模式就是为了在没有经验的情况下写出一手不错的代码,只看不写并不能深刻体验到设计模式的巧妙之处,而学会使用UML进行需求分析,是使用设计模式写好代码的前提。

UML图分类
  • 用例图(Use Case Diagram),描述系统功能;
  • 类图(Class Diagram),描述系统的静态结构;
  • 对象图(Object Diagram),描述系统在某个时刻的静态结构;
  • 组件图(Component Diagram),描述了实现系统的元素的组织;
  • 配置图(Deployment Diagram),描述了环境元素的配置,并把实现系统的元素映射到配置上;
  • 状态图(State Diagram),描述了系统元素的状态条件和响应;
  • 时序图(Sequence Diagram),按时间顺序描述系统元素间的交互;
  • 协作图(Collaboration Diagram),按照时间和空间顺序描述系统元素间的交互和它们之间的关系;
  • 活动图(Activity Diagram),描述了系统元素的活动;

其中类图是描述类与类之间的关系的,是UML图中最核心的。

UML作用
  • 为软件系统建立可视化模型;

  • 能够了解系统的结构和能力;

  • 为软件系统建立构件;

  • 为软件系统建立文档;

什么是模型?模型是对现实世界的形状或状态的抽象模拟和简化。
为什么要建模?最简单的理由:为了能够更好地理解正在开发的系统。

UML 类图

学习设计模式必定需要先读懂 UML 类图,下面就谈谈具体 UML 类图中的概念。类图是用于描述一组类、接口、协作以及它们之间的静态关系。在面向对象系统的建模中,类图是最为常用的图,它用来阐明系统的静态结构。事实上类是对一组具有相同属性、操作、关系和语义的对象的描述,其中对类的属性和操作进行描述时的一个最重要的细节就是它的可见性。

类图的基本符号与含义

1、 类(Class):一般是用三层矩形框表示,第一层表示类的名称,第二层表示的是字段和属性,第三层则是类的方法。第一层中,如果是抽象类,需用斜体显示。

  • 类的属性表达方式

    1
    权限 属性名:类型 [ = 默认值 ]
  • 类的方法表达方式

    1
    权限  方法名称(参数列表) [ : 返回类型]

    注意:public 用 + 表示 ,protected 用 # 表示 ,private 用 - 表示 ,default 用 ~ 表示

类图示

2、接口(interface):接口与类图类似,与类图的主要区别就是顶端有<<interface>>显示。

接口示例图

3、类之间的关系
类与类一共有如下6种关系:泛化(Generalization)、实现(Realization)、组合(Composition)、聚合(Aggregation)、关联(Association)、依赖 (Dependence)。上述6种关系的强弱如下:

1
泛化 = 实现 > 组合 > 聚合 > 关联 > 依赖

类关系图示

类关系图示
  • 泛化(Generalization):表示的是类之间的继承关系,注意是子类指向父类。UML中用带空心三角箭头的实线表示泛化关系,箭头指向的是父类。

    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
    38
    39
    public class People {

    private String name;

    public String getName() {
    return name;
    }

    public void setName(String name) {
    this.name = name;
    }
    }

    public class Student extends People {

    private Long id;

    private Double grade;

    public void study(String course) {
    System.out.println("学习" + course);
    }

    public Long getId() {
    return id;
    }

    public void setId(Long id) {
    this.id = id;
    }

    public Double getGrade() {
    return grade;
    }

    public void setGrade(Double grade) {
    this.grade = grade;
    }
    }
  • 实现(Realization):实现关系用一条带空心箭头的虚线表示。UML中用带空心三角箭头的虚线表示实现关系,箭头指向的是接口。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    public interface IWork {

    void doWork();
    }

    public class People implements IWork{

    private String name;

    public String getName() {
    return name;
    }

    public void setName(String name) {
    this.name = name;
    }

    @Override
    public void doWork() {
    System.out.println("工作");
    }
    }
  • 组合(Composition):是聚合的一种特殊形式,表示的是类之间更强的组合关系。他体现的是一种contains-a的关系,这种关系比聚合更强,也称为强聚合;他同样体现整体与部分间的关系,但此时整体与部分是不可分的,整体的生命周期结束也就意味着部分的生命周期结束。UML中用实心菱形头的实线来表示组合,菱形头指向整体。

例如公司由多个部门组成;公司不存在了,部门也将不存在了。

  • 聚合(Aggregation):用于表示实体对象之间的关系,表示整体由部分构成的语义。与组合关系不同的是,整体和部分不是强依赖的,即使整体不存在了,部分仍然存在;聚合关系是关联关系的一种,耦合度强于关联,他们的代码表现是相同的,仅仅是在语义上有所区别:关联关系的对象间是相互独立的,而聚合关系的对象之间存在着包容关系,他们之间是“整体-个体”的相互关系。UML中用空心菱形头的实线表示聚合关系,菱形头指向整体。

例如一个部门由多个员工组成,部门撤销了,人员不会消失,他们依然存在。

  • 关联(Association):表示的是类与类之间存在某种特定的对应关系。它是一种静态关系,通常与运行状态无关,一般由常识等因素决定的;关联关系默认不强调方向,表示对象间相互知道。UML中用双向、单向带箭头的虚线表示关联关系,箭头两端为相互关联的两个类。

:在最终代码中,关联对象通常是以成员变量的形式实现的;

例如乘车人和车票之间就是一种关联关系。

  • 依赖(Dependency):表示的是类之间的调用关系。与关联关系不同的是,它是一种临时性的关系,通常在运行期间产生,并且随着运行时的变化;依赖关系也可能发生变化;显然,依赖也有方向,双向依赖是一种非常糟糕的结构,我们总是应该保持单向依赖,杜绝双向依赖的产生。UML中用带箭头的虚线表示依赖关系,而箭头所指的则是被依赖的类。
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
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
public class Book {

private String name;

private String author;

private Date publishDate;

private BigDecimal price;

public String getName() {
return name;
}

public void setName(String name) {
this.name = name;
}

public String getAuthor() {
return author;
}

public void setAuthor(String author) {
this.author = author;
}

public Date getPublishDate() {
return publishDate;
}

public void setPublishDate(Date publishDate) {
this.publishDate = publishDate;
}

public BigDecimal getPrice() {
return price;
}

public void setPrice(BigDecimal price) {
this.price = price;
}
}


public class Student extends People {

private Long id;

private Double grade;

public void study(String course) {
System.out.println("学习" + course);
}

/**
* Student的类依赖Book类
*
*/
public void read(Book book) {
System.out.println("阅读" + book.getName());
}

public Long getId() {
return id;
}

public void setId(Long id) {
this.id = id;
}

public Double getGrade() {
return grade;
}

public void setGrade(Double grade) {
this.grade = grade;
}
}

:在最终代码中,依赖关系体现为类构造方法类方法的传入参数,箭头的指向为调用关系;依赖关系除了临时知道对方外,还是“使用”对方的方法和属性;

类继承实现示例图

关联、聚合、组合三种关系用代码表示的话,大多都是一个类是另一个类的成员变量。真正的关系只能配合语义,结合上下文才能够判断出来,而只给出一段代码让我们判断是关联、聚合还是组合关系,则是无法判断的。

[1]参考资料https://zhuanlan.zhihu.com/p/24576502
[2]参考资料https://design-patterns.readthedocs.io/zh_CN/latest/read_uml.html

  • 作者: Sam
  • 发布时间: 2021-01-23 14:17:36
  • 最后更新: 2021-01-23 15:26:07
  • 文章链接: https://ydstudios.gitee.io/post/122fc4b2.html
  • 版权声明: 本网所有文章除特别声明外, 禁止未经授权转载,违者依法追究相关法律责任!