0

Composition is a whole/parts relationship. A common way to code the composition relationship is to create the part object in the constructor of the composite (whole) object. Example in java:

public class Car {

private String brand;
private ArrayList<Tire> theFourTires = new ArrayList<Tire>();

public Car(String brand)
{
    this.brand = brand;
    for (int i = 1; i < 5;i ++)
    {
        // here the "composition" relationship
        theFourTires.add(new Tire());
    }
}

When we want to decide which objects will be the parts, we can use an add ... method to add the part object in the composite. You have to respect this rule (UML specifications) : the part object can not be shared (referenced by another object, except the composite). So, i think it's better, when you call the add method, not to have a reference on the part object in the method calling the add method, just like this, in the Car class:

public void addPart(CarParts aPart)
{
    this.parts.add(aPart);
}

calling the add method from another object:

Car c = new Car("Ford Torino");
c.addPart(new Tire());

instead of

Tire t = new Tire();
c.addPart(t);

because in this case, the instance is shared, by t reference, even if it is for a very short time, and the composition relationship becomes an aggregation. In this case, you could call method on t object and violate encapsulation of the part object. The part objects have to be managed by the composite only. What do you think about this ? Thanks world !

Alan Allen
  • 71
  • 5
  • 2
    Please use *StackExchange* for questions like this. Here we just want to fix real errors and no gerneal disscussions. – LenglBoy Jun 12 '18 at 09:02
  • There's nothing wrong with doing it the second way. The tire is only declared as a local variable inside a mehod, and is not referenced by the other object. In no way does this constitute aggregation. By your logic, calling `System.out.println()` would also aggregate the standard output stream. – Robby Cornelissen Jun 12 '18 at 09:05
  • If you really need the system to enforce that objects are not shared (maybe code review is good enough?), you could pass a Builder instance to your `addPart` method. The `Car` can then call `build` on that and be sure (as long as the builder does its job) that it gets a fresh, unshared instance. Or a Builder could build the whole object graph in one go. But this could easily be over-engineering it. – Thilo Jun 12 '18 at 09:05
  • When i "said the relationship becomes a aggregation", it was about the Car class and the Tire class association. In the last snippet of code, there is just a dependency between Tire and the class containing this snippet, because i use a local variable. About System.out.println() example, out is a public and static reference and calling it from a class C is also just a dependency between class C and PrintStream class. However there is a aggregation between System and PrintStream class. In the last snipppet, as long as the method is running, the garbage collector does not delete the Tire object – Alan Allen Jun 12 '18 at 14:05

3 Answers3

1

I don't think it matters at all, since, as long as you have a getter to access your 4 tires, you can get a reference to the Tire object which is not managed by Car anymore.

Since there is no delete operator in Java, the Car object has no possibility to delete the 4 Tire objects that it is linked to, and consequently there is no need for a composition type of relationship, and it isn't possible to materialize it either code wise.

AntoineB
  • 4,535
  • 5
  • 28
  • 61
  • If you assign null to the unique reference Car object, the 4 tires will be deleted too if this 4 objects are not shared. If you have getter to access tires, this getter have to return references to cloned tires. But a getter is not a good idea in that case. A simply and good example of this is ArrayList java class, composed with an array, full management of it is the ArrayList class responsability. The getters methods toArray of ArrayList class returns copy respecting the no sharing rule. – Alan Allen Jun 12 '18 at 14:26
0

A given association may or may not be navigable, and may or may not be a composition. If it is navigable, then something else can navigate it and get to the target of the association (the tyre) from the source (the car). Navigability does not affect whether the association is a composition. Encapsulation enforces navigability, not composition.

Pete Kirkham
  • 48,893
  • 5
  • 92
  • 171
0

Wouldn't it be the best to create a defensive copy in the addPart() method? Something like that:

public void addPart(CarParts aPart)
{
    this.parts.add(new CarParts(aPart);
}

I assume you want those to be inaccessible by everyone.

Amongalen
  • 3,101
  • 14
  • 20