jdecer
jdecer

Reputation: 81

Is this an example of a composition relationship?

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

Upvotes: 3

Views: 100

Answers (1)

Christophe
Christophe

Reputation: 73617

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>?

Upvotes: 3

Related Questions