Snapshot diagram (代码快照图)
- 用于描述程序运行时的内部状态,包括堆和栈的调用。
- 刻画各类变化随时间的变化,描述各类概念如:原始类型/对象类型,不可变对象/可变对象,引用别名
- 刻画基本类型的值:直接用一个箭头指向它。
- 刻画对象类型的值:用圈圈起来,再用一个箭头指向它,在圈的里面有一个label来标识它的类型。圈的内部可以包含类的各个属性(基本类型/对象类型),一个箭头由属性的名字指向属性的值。
- 不可变对象的值用双线椭圆来表示,如String,下图中s所指向的String对象就发生了改变。
- 可变对象的值用单线椭圆来表示,可变对象内部属性的值可以发生改变,如StringBuilder。
- 不可变的引用(用final修饰)用双线箭头来表示。如下图中,id是不可变的,age是可变的。
- 有的时候,变量的引用是不可变的,即只能指向这唯一一个对象,但这个对象的值是可以改变的,如final StringBuilder。
- Example
下面这段代码的Snapshot diagram。
String s1 = new String("abc");
List<String> list = new ArrayList<>();
list.add(s1);
s1 = s1.concat("d");
System.out.println(list.get(0));
String s2 = s1.concat("e");
list.set(0, s2);
System.out.println(list.get(0));
UML类图
类图基础属性
+表示public
-表示private
#表示protected
~表示default,也就是包权限
_下划线表示static
斜体表示抽象类
在UML中,类使用包含类名、属性和操作且带有分隔线的长方形来表示,如定义一个Employee类,它包含属性name、age和email,以及操作modifyInfo(),在UML类图中该类如图所示:
在UML类图中,类一般由三部分组成:
类名、属性、操作
UML规定属性的表示方式为:可见性 名称:类型 [ = 缺省值 ]
UML规定操作的表示方式为:可见性 名称(参数列表) [ : 返回类型]
对于接口,可以在接口名的上方写\<\<interface>>
类与类之间关系
在UML类图中,常见的有以下几种关系: 泛化(Generalization), 实现(Realization),关联(Association),聚合(Aggregation),组合(Composition),依赖(Dependency)
下面是一幅从网上摘取的生动形象的图。
1. 关联关系
关联关系通常将一个类的对象作为另一个类的成员变量。在使用类图表示关联关系时可以在关联线上标注角色名,一般使用一个表示两者之间关系的动词或者名词表示角色名。
如在一个登录界面类LoginForm中包含一个JButton类型的注册按钮loginButton,它们之间可以表示为关联关系,代码实现时可以在LoginForm中定义一个名为loginButton的属性对象,其类型为JButton。
关联关系又分为单向关联、双向关联、自关联、聚合关系、组合关系。
其中聚合关系和组合关系比较特别。
聚合(Aggregation)关系表示整体与部分的关系。在聚合关系中,成员对象是整体对象的一部分,但是成员对象可以脱离整体对象独立存在。在UML中,聚合关系用带空心菱形的直线表示。例如:汽车发动机(Engine)是汽车(Car)的组成部分,但是汽车发动机可以独立存在,因此,汽车和发动机是聚合关系。
在代码实现聚合关系时,成员对象通常作为构造方法、Setter方法或业务方法的参数注入到整体对象中,上图对应的Java代码片段如下:
public class Car {
private Engine engine;
//构造注入
public Car(Engine engine) {
this.engine = engine;
}
//设值注入
public void setEngine(Engine engine) {
this.engine = engine;
}
}
public class Engine {
}
组合(Composition)关系也表示类之间整体和部分的关系,但是在组合关系中整体对象可以控制成员对象的生命周期,一旦整体对象不存在,成员对象也将不存在,成员对象与整体对象之间具有同生共死的关系。在UML中,组合关系用带实心菱形的直线表示。例如:人的头(Head)与嘴巴(Mouth),嘴巴是头的组成部分之一,而且如果头没了,嘴巴也就没了,因此头和嘴巴是组合关系,如图所示。
public class Head {
private Mouth mouth;
public Head() {
mouth = new Mouth(); //实例化成员类
}
……
}
public class Mouth {
……
}