3

This is a rephrased question of one I asked previousy, but which wasn't well formulated and contained a few errors (incl. the answer I referred to, sorry about that) so I try again, in the hope that this question makes more sense.

I got confused over one of the answers in the following thread and I'm referring to the code snippet in the third answer (currently ca 117 upvotes):
Prefer composition over inheritance?

The answer illustrates composition using dependency injection see code snippet there).

Edit: repeated below:

class Person {
   String Title;
   String Name;
   Int Age;

   public Person(String title, String name, String age) {
      this.Title = title;
      this.Name = name;
      this.Age = age;
   }

}

class Employee {
   Int Salary;
   private Person person;

   public Employee(Person p, Int salary) {
       this.person = p;
       this.Salary = salary;
   }
}

Person johnny = new Person ("Mr.", "John", 25);
Employee john = new Employee (johnny, 50000);

What confuses me is that at school, we learned about:
- Direct association (not relevant for this question);
- Aggregation: weak relationship -> has-a-relationship;
- Composition: strong relationship -> ownership where one can't live without the other.

Examples given at school implied DI to be a part of aggregation, because it indicates a weak relationship.
Opposite to composition, where the examples indicate that ClassB is instantiated either in the constructor of classA, or by a setter of classA. ClassA is herewith explicitly responsible for the creation of classB (otherwise classB cannot exist).
The example given was a Person class where the Heart class was instantiated in the constructor of the Person class.

Is the assumption correct that dependency injection implies aggregation, or could one also have DI with composition?

Community
  • 1
  • 1
html_programmer
  • 18,126
  • 18
  • 85
  • 158
  • Might be helpful: http://stackoverflow.com/questions/1644273/what-is-the-difference-between-aggregation-composition-and-dependency – christopher Aug 19 '15 at 19:44
  • @christopher Event the top answer to the thread you shared indicates that dependency is a form of association, which is a weak relationship. So I assume that you cannot have DI with composition? – html_programmer Aug 19 '15 at 19:46
  • Well DI *implies* that the child object existed before the object that it is being passed into, so logically it just doesn't seem reasonable. – christopher Aug 19 '15 at 19:47
  • Hm ok, that's what I would expect. Just got confused over the code snippet and wanted some confirmation. – html_programmer Aug 19 '15 at 19:48
  • 1
    Well in the example provided, the object `Person` exists entirely independently of the object `Employee`, both in code and conceptually. A person can not have a job, and therefore they aren't an employee. Now whether a person `has a` `Employee` or a `Person` *is a* `Employee` is a different discussion. – christopher Aug 19 '15 at 20:06
  • 1
    @christopher I agree that it doesn't appear to be the best example. Unless bears can become employees, I imagine that inheritance would be a better option here... – html_programmer Aug 19 '15 at 20:18
  • I remember learning about the 'differences' between composition and aggregation in school, too. But then when I got into the real world, composition the only term I heard to describe any has-a relationship. The only place I've heard of aggregation is in DDD, namely, the term Aggregate Root. I know this isn't an answer, but just wanted to let you know not to sweat over it. – jmrah Aug 20 '15 at 02:01

1 Answers1

0

The key to understanding a composition relationship is that the contained object is known, and used, by nothing except the container object. In the human contains hart example, interactions with a human never involve directly manipulating the hart. Thus it is a containment relationship. If the heart is exposed for others to manipulate, then it would be an aggregation relationship.

Now just because the object that constructs the Employee must construct the contained Person doesn't stop the relationship from being one of containment. The key in your example is that the person field is private and there is no way outside of the employee object to manipulate its person. That's what makes it containment rather than aggregation.

I grant that you could setup a nasty case where the object that constructs john, holds on to johnny and proceeds to manipulate it. In effect, this object would be changing the state of john without calling any of its methods. This is very poor practice, don't do it.

-- continuation --

And to riff off of the "prefer containment over inheritance" idea. I suggest you prefer containment over aggregation as well. A containment relation means that a significant portion of the application can ignore the fact that the contained class even exists in the system. This is because all their interaction is with the container rather than the contained.

Of course sometimes containment isn't possible and aggregation is logically necessary to express the relationship in question.

Daniel T.
  • 32,821
  • 6
  • 50
  • 72