依赖关系
依赖关系是类与类之间的连接,是一种使用与被使用的关系。双方都不用定义对方的对象属性,只在方法中使用类。
关注点:
- 无需定义对象属性。
- 在方法内部创建依赖类的对象,或者调用依赖类的静态方法,或者依赖对象最为方法参数使用。
- 类与类之间的关系在同一层次上。
例如司机开车,司机与车是使用与被使用的关系。
UML图
使用带箭头的虚线表示依赖关系,箭头指向被依赖的类。
代码
class Car{
public void move()
//车子会移动
}
class Driver{
public void drive(Car car){
car.move();
}
}
关联关系
关联关系也是类与类之间的连接。是一个类知道另一个类的属性和方法,也就是说需要定义(拥有)另一个类的对象属性。关联可以是单向,也可以是双向。
关注点:
- 必须定义对象属性。
- 类与类之间的关系在同一层次上。
依赖和关联的区别在于依赖是使用,关联是拥有。
UML图
使用箭头标记关联关系
如果是双向关联,可以使用双箭头或者不带箭头表示:
使用UML对母亲和孩子的关联关系进行建模
代码
孩子类
class Child {
Mother mother;
}
母亲类
class Mother {
List<Child> children;
}
聚合关系
聚合是关联关系的一种,是一种强关联关系(has a),是一种整体与个体/部分的关系。两个类处于不同的层次上,一个类是整体,一个类是部分或者个体。个体可能被多个整体共享,删除整体,个体可以单独存在,删除个体,也不影响整体,整体和个体可单独存在。例如:班级和学生,学生会和学生,删除班级,学生还存在,学生还跟学生会这个整体关联。
关注点:
- 必须定义对象属性。
- 类与类之间的关系在不同层次上,是整体与个体/部分的关系。
- 整体与个体都可单独存在,生命周期没有关联。
UML图
使用空的菱形表示整体
对班级和学生UML建模。
代码
整个和个体有自己的源文件
个体Student类
class Student {
}
整体Class类
class Class {
List<Student> students;
}
或者使用静态内部类
class Class {
List<Student> students;
static class Student {
}
}
注意如果要在个体中引用整体对象,需要在个体类中添加整体对象属性。
可以发现聚合关系跟关联关系很像,我们不能从代码上根据引用来区分聚合还是关联,只能从逻辑上进行区分,即是不是整体与个体的关系。
组合关系
组合也是关联关系的一种,比聚合更强的关联关系,也是整体与个体/部分的关系。
类与类之间是has a
或者 belong to
的关系,整体或者说是容器has a
个体/部分,即整体拥有个体的对象属性;个体belong to
整体。
两个类处于不同层次上,整体负责个体的生命周期,删除整体,个体也随之删除,但是删除个体,不影响整体的存在。
例如:人与四肢,人没了,四肢也会腐朽;四肢没了,但是人还可以活着,就是比较痛苦。房子与房间,房子塌了,房间也没了;房间砸掉了,但是房子还好好的。
关注点:
- 必须定义对象属性。
- 类与类之间的关系在不同层次上,是整体与个体/部分的关系。
- 整体负责个体/部分的生命周期,整体删除,个体也随之删除。
UML图
注意菱形所在的这一方是整体,另一方是个体/部分。也可以加上箭头来更清洗的表示:
房子与房间的UML示例:
房子是整体,拥有个体房间对象属性。
代码
在Java中,可以使用非静态内部类在建模,将个体实例Room绑定到整体Building。
class Building
List<Room> rooms;
class Room {}
}
请注意,所有内部类对象都存储对其包含对象的隐式引用。因此,我们不需要手动存储它来访问它:
class Building {
String address
class Room {
String getBuildingAddress() {
return Building.this.address;
}
}
}
聚合与组合的区别
- 聚合个体脱离整体可以单独存在。
- 组合个体不能脱离整体单独存在。
依赖、关联和聚合、组合的区别
依赖、关联:类之间的关系在同一层次上。
聚合、组合:类之间是整体与部分的关系。
关联、聚合、组合只能配合语义,结合上下文才能够判断出来,而只给出一段代码让我们判断是关联,聚合,还是组合关系,则是无法判断的。
耦合度强弱
耦合度强度依次增强:依赖<关联<聚合<组合