我对组成(有)关系感到困惑。我很清楚,例如汽车类has a
汽车类。我的问题是关于他们在逻辑上不拥有另一个类的类,而是在物理上拥有它们以便使用它们。您必须有一个引用或拥有一个类才能使用它的方法,但有时它在逻辑层面上没有意义。例如,假设有一个类garbage man
并且是另一个类waste container
。垃圾人使用empty
废物容器的方法和为了使用它的方法,有一个废物容器的参考。这是否意味着垃圾人在面向对象的设计上有一个(嗯,多个)废物容器?我会说垃圾人使用垃圾容器,但这让我感到困惑,因为垃圾人身体上有它。有人可以告诉我逻辑吗?
2 回答
有您拥有的对象和您引用的对象。如果包含对象拥有被包含对象,则意味着包含对象负责被包含对象的生命周期——创建它,处置它(如果它是一个可以处置的对象)。所有者还可以将包含对象的所有权传递给另一个对象。
您引用的对象是您可以使用但不拥有的对象。所有者通常会给您一个对象的引用(可能通过将其作为参数传递给函数调用),并保证在您拥有引用时对象处于有效状态(某些环境通过提供自动垃圾收集)
“拥有”关系可能是拥有或引用,并且大多数计算机语言不包括对引用/所有权区别的明确支持,但在设计中保持直截了当是一个重要概念。UML 建模语言确实对这种区别进行了建模:所有权表示“复合”关系,而引用是“聚合”关系。
GarbageMan
没有, WasteContainer
因为废物容器不以任何方式描述垃圾人或以任何方式扩展其属性。
我想你在这里错过了一个手术。 WasteContainer
有一个empty()
方法,因为这是可以对其执行的操作。但GarbageMan
也有手术。一个GarbageMan
可以performJob()
。 这就是 a 的WasteContainer
用武之地。考虑这样的事情(与语言无关):
class WasteContainer {
empty() { ... }
}
class GarbageMan {
performJob(Collection<WasteContainer> containers) {
foreach (var container in containers) {
container.empty();
}
}
}
AGarbageMan
知道 WasteContainer
s,因为那是他工作的一部分。但他没有s , WasteContainer
因为维持他们的状态不是他工作的一部分。他对它们进行了手术,但并不拥有它们。
这可以通过使用接口进一步抽象。例如:
interface Emptyable {
empty();
}
class WasteContainer : Emptyable {
empty() { ... }
}
class GarbageMan {
performJob(Collection<Emptyable> bins) {
foreach (var bin in bins) {
bin.empty();
}
}
}
现在GarbageMan
与WasteContainer
. 可以清空的容器有很多种,一个GarbageMan
可以处理所有的容器。操作的执行方式相同,只需向他提供一组容器GarbageMan
,他就会完成他的工作。
这似乎更紧密地模拟了正在观察的现实世界场景,而不是GarbageMan
拥有WasteContainers
. 可能会有一些Employer
管理哪些WasteContainers
被发送到特定GarbageMan
实例,可能有不同Customer
的 s 实际拥有WasteContainer
s 或其他类型的Emptyable
s,等等。