Thursday, January 06, 2011

Dependency Injection - some updates

I finally found a succinct and clear definition of Dependency Injection:

Dependency injection means giving an object its instance variables instead of letting it create them.

based on answers to What is dependency injection? on Stackoverflow. There are some variations on how you do that - you can pass the instance variables in the call to the object creator (the new method) or you can use a setter to pass it to the object after it is created. This is exactly what I was thinking. Inversion of Control here happens only if you use a framework that takes over the object creation - but this is not required for the practice of DI. The name does not fit too well to its definition - but it is probably too late to change it.

Reasons to do DI:

  1. The most immediate reason is that it makes it easy to use mockups (or even undef's or Nulls) for the dependencies in tests. But this is is just a concrete example of the more general reasons that follow.
  2. To change the coupling between the main class and the dependency from control coupling to data-structured coupling (Types of coupling in wikipedia). Intuitively this also means increasing the encapsulation of the main module.
  3. To remove more frequently changing code from inside of less frequently changing code. There is an analogy between hardcoded literal constants and hardcoded objects - this is the main subject of my previous post.

It is worth noting that Moose by taking over the new method encourages DI, but of course people will always find ways to sidestep this by creating an init or setup method or using BUILD or BUILDARGS from the Moose API.


Hans Dieter Pearcey said...

"Moose taking over the new method" does not particularly encourage DI, since there is still BUILD and default/builder.

zby said...

Yeah - this is true - but BUILD is not advertised that much. As to default/build - with them at least you *can* use DI. They can so be used as a transition step towards pure DI.