4
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;
    }
}

In my understanding, when we construct the part object within the whole, the relationship is composition, which results in the part being destroyed along with the whole.

In this case since we allocate new data onto the polygon LinkedHashSet and deep-copy the Line objects in the constructor is it safe to assume this is a composition relationship between Polygon (being the whole) and Line (being the part)? In this case it definitely seems that the data in polygon variable will be destroyed when the object is destroyed.

Something like this

jdecer
  • 81
  • 4
  • 1
    It's not a full deep copy. You copy line l-by line, but the line is an object, so the same object is used in the two hash sets. For a deep copy, you'd need to clone() the lines, i.e. constructing a copy of the the line. – Christophe Oct 08 '22 at 17:38

1 Answers1

3

The composition, or more precisely the composite aggregation, means that there is an exclusive ownership and control over the lifecycle of the composed objects.

Your initial code

The Line elements of the Polygon may very well be shared between several polygons, in view of Java's reference assignment principle. Maybe they are not, but the exclusive ownership is not guaranteed.

In your UML diagram you could therefore consider shared aggregation, which is commonly understood as a loser part-whole aggregation without exclusivity requirement. But the current UML specification no longer defines the semantic of the shared aggregation. So in practice, I'd recommend a simple association, with an unambiguous semantic.

Your edited question

If you'd make a deep copy, including cloning every input Line, you would have a reasonable assurance that the line is not reused from somewhere else:

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)); 
    }
}

You should then also prevent leaking the polygon's lines by make sure that you never return the lines from any method but only clones, from the polygon. In this case, the composite aggregation would be correct.

Unrelated: Your constructor seems to leak some implementation details. Is there a reason to use a LinkedHashSet<Line> argument and not a more general Collection<Line>?

Christophe
  • 68,716
  • 7
  • 72
  • 138
  • Your definition of shared aggregation is plain wrong and not defined as such in UML 2.5 (see p. 110 you know by heart as I know). I also know that the definition there is odd (to be polite). – qwerty_so Oct 08 '22 at 20:53
  • @qwerty_so the shared aggregation was explained like this by the UML inventors, and up to UML 1.4 defined as a part-whole relation (see UML1.4 page 2-66: "*an aggregation; that is, a whole/part relationship. (...) Composite aggregation is a strong form of aggregation, which requires that a part instance be included in at most one composite at a time (...)*" - This is why I wrote "is in principle" and "common understanding" (since many still use it like that). I nevertheless explicitly state that shared aggregation has now no semantics defined in the UML specs, and I wonder what is wrong here – Christophe Oct 08 '22 at 21:05
  • Well, the definition says that there is no definition (unless you invent your own). So the first sentence about shared semantics is broken by the 2nd one which tells that is has no semantics. As long as OMG does not come up with some clear (non-)definition I recommend to not use this connector at all. – qwerty_so Oct 09 '22 at 09:11
  • 1
    @qwerty_so I've reworded slightly to avoid any misunderstanding about definitios – Christophe Oct 09 '22 at 10:22
  • Actually I would regard the UML documentation as buggy in that respect. They say it has _shared aggregation semantics_ without defining it. Here we call that Siemens Air Hook... – qwerty_so Oct 10 '22 at 11:45