这是一个组合关系的例子吗?

3
class Polygon {
    private final LinkedHashSet <Line> polygon;
    private int objID;
    private static int classID;
    Iterator <Line> it;

    public Polygon(LinkedHashSet<Line> polygon) {
        this.polygon = new LinkedHashSet<Line>();
        for(Line l: polygon)
            this.polygon.add (l);
        objID = ++ classID;
        it = this.polygon.iterator();
    }
}


class Line {
    Point start, end;

    public Line(Point a, Point b){
        start = a;
        end = b;
    }
}

在我的理解中,当我们在整体中构建“部分”对象时,关系是“组合”,这导致部分随整体一起被销毁。
在这种情况下,由于我们在构造函数中将新数据分配到多边形LinkedHashSet上并深度复制线对象,因此可以安全地假设这是多边形(作为整体)和线(作为部分)之间的“组合”关系吗?在这种情况下,当对象被销毁时,变量“polygon”中的数据肯定会被销毁。

Something like this


1
这不是完全的深拷贝。你是逐行复制,但每一行都是一个对象,所以两个哈希集合中使用的是同一个对象。要进行深拷贝,你需要clone()这些行,即构造行的副本。 - Christophe
1个回答

3

组合聚合,更准确地说,是指对所组成的对象的生命周期具有独占的所有权和控制。

您最初的代码

由于 Java 的引用赋值原则,PolygonLine 元素可能会在多个多边形之间共享。也许它们不是这样的,但是独占所有权并不能得到保证。

因此,在您的 UML 图中可以考虑共享聚合,它通常被理解为没有排他性要求的部分整体聚合。但当前的 UML 规范不再定义共享聚合的语义。因此,实际上,我建议使用简单关联,具有明确的语义。

您编辑后的问题

如果进行深拷贝,包括克隆每个输入的 Line,则可以合理地保证该线段未从其他位置重复使用:

class Polygon {
    ...
    public Polygon(Collection<Line> polygon) {
        this.polygon = new LinkedHashSet<Line>();
        for(Line l: polygon)
            this.polygon.add (l.clone());
        objID = ++ classID;
        it = this.polygon.iterator();
    }
}
class Line {
    ...
    public Line(Point a, Point b){
        ...
    }
    public Line clone() {
        return (new Line(start, end)); 
    }
}

你还应该通过确保从多边形中仅返回克隆对象而不是任何方法的线条来防止泄漏多边形的线条。在这种情况下,复合聚合将是正确的。

无关: 你的构造函数似乎泄漏了一些实现细节。是否有使用LinkedHashSet<Line>参数而不是更通用的Collection<Line>的原因?


你对共享聚合的定义是错误的,而且在UML 2.5中也没有这样定义(就像我知道的那样,它在第110页)。我也知道那里的定义很奇怪(委婉地说)。 - qwerty_so
@qwerty_so,UML的发明者解释了共享聚合的含义,并在UML1.4中将其定义为部分整体关系(参见UML1.4第2-66页:“聚合;即整体/部分关系。(...)组合聚合是聚合的一种强形式,要求一个部分实例最多同时包含在一个组合中(...)”)。这就是我为什么写“原则上”和“共同理解”的原因(因为许多人仍然像这样使用它)。尽管如此,我明确声明,在UML规范中,共享聚合现在没有定义语义,我想知道这里有什么问题。 - Christophe
好的,定义说没有定义(除非你自己发明一个)。因此,关于共享语义的第一句话被第二句话打破了,第二句话告诉我们它没有语义。只要OMG没有提出明确的(非)定义,我建议根本不要使用这个连接器。 - qwerty_so
1
@qwerty_so 我稍微改了一下措辞,以避免对定义产生任何误解。 - Christophe
实际上,我认为在这方面 UML 文档存在缺陷。它们说它具有“共享聚合语义”,但没有定义它。在这里,我们称之为西门子气钩... - qwerty_so

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接