UML类图速查手册
📘

UML类图速查手册

Created
May 22, 2024 02:57 PM
Tags
适用于有一定的UML概念及基础某个时间需要重新记忆
 

🤔 快速回忆

 
包含所有关系的示例,忽略内部细节
包含所有关系的示例,忽略内部细节
 
  • 车的类图结构为<<abstract>>,表示车是一个抽象类;
  • 它有两个继承类:小汽车和自行车;它们之间的关系为实现关系,使用带空心箭头的虚线表示;
  • 小汽车为与SUV之间也是继承关系,它们之间的关系为泛化关系,使用带空心箭头的实线表示;
  • 小汽车与发动机之间是组合关系,使用带实心箭头的实线表示;
  • 学生与班级之间是聚合关系,使用带空心箭头的实线表示;
  • 学生与身份证之间为关联关系,使用一根实线表示;
  • 学生上学需要用到自行车,与自行车是一种依赖关系,使用带箭头的虚线表示;
 
 

👨

Person 类为例,Java 代码长这样:
public class Person { private String ; private int age; public Person(String initialName) { this.name = initialName; this.age = 0; } public void printPerson() { System.out.println(this.name + ", age " + this.age + " years"); } public String getName() { return this.name; } }
对应的类图应该是:
Person 类
Person 类
 
 
 

↗️ 关联与依赖

关联 (association)

关联通常表示一个类包含对另一个类的引用,即一个类的实例可以访问另一个类的实例,注意它描述的是对象之间静态的、天然的结构,通常与运行状态无关,可以与依赖关系放一起细细品味。
下面我们有一本书 Book 类,注意到里面有对 Person 对象的引用,那么对应的代码和类图:
 
public class Book { private String name; private String publisher; private Person author; // constructors and methods }
 
关联关系是用一条直线表示,可以带箭头;表示不同类的对象之间的静态结构关系;
关联关系是用一条直线表示,可以带箭头;表示不同类的对象之间的静态结构关系;
 
关联关系默认不强调方向,可以是双向的,也可以是单向的,直线表示对象间相互知道,带箭头表明:一本书知道它的作者,但一个人不知道书的存在;在箭头一端添加标签可以进一步描述连接。
 
那如果一本书有不止一个作者呢?
 
public class Book { private String name; private String publisher; private List<Person> authors; // constructors and methods }
这种情况要如何表示呢?
 
在类图中,通过在箭头末尾添加星号*来描述这种多重性,*告诉我们一本书可以有多个作者,如果你想更具体,可以标上 1..*1..3 表示至少有1个或1~3个。
 
notion image
 

依赖 (dependency)

我们在关联关系中强调了“静态”一词,那么依赖关系则更为“动态”。
依赖关系表示一个类使用另一个类,但这种使用是临时的、短期的。依赖关系表示一个类的方法参数或局部变量引用另一个类,也就是说这种关系通常在运行期间产生,并且随着运行时的变化。
假设我们有一个表示订单 Order 和支付处理 PaymentProcessor 之间的关系,订单类在支付过程中依赖于支付处理类,那么对应的代码和类图:
 
public class Order { private int id; private double amount; public Order(int id, double amount) { this.id = id; this.amount = amount; } public void processPayment(PaymentProcessor processor) { processor.process(amount); } }
Order
public class PaymentProcessor { public void process(double amount) { System.out.println("Processing payment of amount: " + amount); } }
PaymentProcessor
 
依赖关系是用一套带箭头的虚线表示的;表示A依赖于B,A在运行期间会用到B的关系;
依赖关系是用一套带箭头的虚线表示的;表示A依赖于B,A在运行期间会用到B的关系;
 
在最终代码中,依赖关系体现为类构造方法及类方法的传入参数,箭头的指向为调用关系;依赖关系除了临时知道对方外,还能“使用”对方的方法和属性;
 
显然,依赖也有方向,一般都是单向依赖,双向依赖是一种非常糟糕的结构,我们总是应该保持单向依赖,杜绝双向依赖的产生;
 

⏹️ 聚合与组合

聚合 (Aggregation)

聚合在关联的基础上多了一层语义:表示整体由部分构成
假设我们有一个表示部门 Department 的类和一个表示员工 Employee 的类。在这个例子中,“部门”包含多个“员工”,但“员工”可以独立于“部门”存在。对应的代码和类图:
 
public class Employee { private String name; private int id; // constructors and methods }
Employee
public class Department { private String name; private List<Employee> employees; // constructors and methods }
Department
 
聚合关系用一条带空心菱形箭头的直线表示,表示A聚合到B上,或者说B由A组成;
聚合关系用一条带空心菱形箭头的直线表示,表示A聚合到B上,或者说B由A组成;
 

组合 (composition)

组合是在聚合的基础上更进一层的同生共死的绑定:表示整体由部分构成,但当整体被销毁时,所包含的部分也会被销毁
假设我们有一个表示房子 House 的类和一个表示房间 Room 的类。在这个例子中,“房子”包含多个“房间”,“房间”不能独立于“房子”存在。对应的代码和类图:
 
public class Room { private String name; private int size; // constructors and methods }
Room
public class House { private String address; private List<Room> rooms; // constructors and methods }
House
 
组合关系用一条带实心菱形箭头直线表示,表示若干的A组成B,或者B由A组成;
组合关系用一条带实心菱形箭头直线表示,表示若干的A组成B,或者B由A组成;
 
📌
组合和聚合的区别在于:组合关系是一种强依赖的特殊聚合关系,如果整体不存在了,则部分也不存在了,没了房子就没有房间,而在聚合的例子中,没有员工的部门依然可以存在(尽管看起来很诡异)。
 

🔼 实现与泛化

实现 (realize/implements)

实现关系用于表示一个类实现一个接口。接口定义了一组方法,具体的实现由实现类提供。实现表示的是"can-do"关系,即实现类可以做接口规定的事情。
 
假设我们有一个接口 Flyable 和一个实现该接口的类 Bird,表示 Bird 实现了 Flyable 接口的功能。那么对应的代码和类图:
 
public class Bird implements Flyable { public void fly() { System.out.println( "The bird flies."); } }
Bird
public interface Flyable { void fly(); }
Flyable
 
实现关系用一条带空心箭头的虚线表示;表示A实现了B定义的行为
实现关系用一条带空心箭头的虚线表示;表示A实现了B定义的行为
 
实现关系表现为继承抽象类或接口
 

泛化 (Generalization)

泛化关系用于表示类之间的继承关系,子类继承父类的属性和方法。泛化表示的是"is-a"关系,即子类是父类的一种特殊化。
 
假设我们有一个基类 Animal 和一个子类 Dog,表示 Dog 是一种 Animal。那么对应的代码和类图:
public class Dog extends Animal { public void bark() { System.out.println("The dog barks."); } }
Dog
 
public class Animal { public void eat() { System.out.println("This animal eats food."); } }
Animal
泛化关系用一条带空心箭头的直接表示;表示A继承自B;
泛化关系用一条带空心箭头的直接表示;表示A继承自B;
 
泛化关系表现为继承非抽象类
 
 

📚 参考

 
 
绘图工具:ioDraw (有点难用😿)