1. 关系强弱顺序(由强到弱)
- 泛化
- 实现
- 组合
- 聚合
- 关联
- 依赖
图中,组合和聚合标错了
2. 依赖
虚线箭头
,箭头指向被依赖类
- 依赖关系描述了两个类之间的临时关系。通常不会持续整个对象的生命周期,而是创建一个临时的关系以满足特定操作。
一个类的对象或方法依赖于另一个类的对象或方法时,它们之间存在依赖关系。
依赖关系一般一个类的对象不会持有另一个类的对象- 依赖关系在类之间创建了解耦,使得一个类的修改不至于影响到其他类。
type DataLoader interface {
LoadData() []string
}
type DataProcessor struct{}
func (dp *DataProcessor) ProcessData(loader DataLoader) {
data := loader.LoadData()
// 处理数据的逻辑
}
DataProcessor 类依赖的是DataLoader接口,而不是具体的实现,这样我们替换了DataLoader的实现而不用修改DataProcessor类
- 依赖关系通常有“使用 ”、“需要”,或者“依赖于”等特点。
3. 关联
泛化和实现,其他的都是关联关系
- 关联关系分为两种,
强关联和弱关联
弱关联: 依赖关系
强关联:聚合关系、组合关系
3.1 按关联方式分类
- 双向关联:
实线表示
,你也可以两端都带箭头 - 单向关联:
实线箭头
- 自关联:
同一个类的对象之间的关联
- 多重性关联:
在关联上限定上最大最小实例数
在多重性关联中,我们用实线表示,并在两端标好数字限定
注意,关联关系即可以按关联方式分类,也可以按关联性强弱分类。是按两种维度来进行划分的。 关联方式与关联性强弱没有相关性
3.2 关联的多重性
示例 | 描述 |
---|---|
0 | 0 个 |
1 | 1 个 |
0 … 1 | 0个或1 个 |
* | 多个, 包括 0个 |
0… * | 0到 n 个 |
1…* | 1到 n个 |
2…6 | 2到 6个 |
3.3 按关联强度分类
强关联
- 强关联表示两个类之间的紧密联系。
- 强关联关系中,一个类包含对另一个类对象的直接引用,通常作为成员或实例变量。
- 组合和聚合都属于强关联的一种。 但聚合的关联性要更弱一些。
- 在强关联中,对象的生命周期
可能
相互依赖。
type Engine struct {
// 引擎的属性和方法
}
type Car struct {
engine *Engine
}
func NewCar() *Car {
engine := &Engine{}
return &Car{engine: engine}
}
在这个示例中,Car 类和 Engine 类之间存在强关联关系,因为每辆车都拥有(包含)一个引擎,而引擎也是车的一个组成部分。在 NewCar 函数中,当我们创建一个新的 Car 实例时,同时也会创建一个新的 Engine 实例。如此一来,Car 对象的生命周期和 Engine 对象的生命周期就相互依赖了。
弱关联
- 弱关联表示两个类之间的相对较弱的联系。通常通过间接方法如
接口
或回调函数
来维护联系。 - 在弱关联中,
一个类不会直接包含对另一个类对象的引用。
(不会直接引用另一个类对象,但可以直接引用接口、抽象类。或者在方法中通过参数使用而不是直接引用) - 当一个类发生改变时,另一个关联类可能不会受到直接影响。
- 弱关联可以实现更高程度的解耦,便于代码的维护和扩展。
依赖
就是一种弱关联
4. 聚合
尾部空心菱形的实线箭头
箭头可以省略,箭头指向整体- 聚合是一种表示
整体和部分之间关系
的较弱关联。 - 在聚合关系中,整体(容器类)和部分(构成类)的生命周期是相对独立的。
- 部分可以脱离整体独立存在
- 如鸟群和鸟,他们的生命周期相对独立。
5. 组合
尾部实心菱形的实线箭头
,箭头可以省略,箭头指向整体- 组合是一种表示整体和部分之间关系的较强关联。
- 在组合关系中,整体(容器类)和部分(构成类)的生命周期是紧密相关的。
- 身体(Body)和心脏(Heart)之间的关系可以看作是组合关系。一个身体包含一个心脏,当身体不存在时,心脏也不存在。
6. 泛化
实线空心三角箭头
,三角箭头指向父类- 是一种子类和父类之间继承关系
7. 实现
虚线空心三角箭头
,三角箭头指向接口- 是一种类于接口之间的关系