views:

215

answers:

5

So I've got maybe 10 objects each of which has 1-3 dependencies (which I think is ok as far as loose coupling is concerned) but also some settings that can be used to define behavior (timeout, window size, etc).

Now before I started using an Inversion of Control container I would have created a factory and maybe even a simple ObjectSettings object for each of the objects that requires more than 1 setting to keep the size of the constructor to the recommended "less than 4" parameter size. I am now using an inversion of control container and I just don't see all that much of a point to it. Sure I might get a constructor with 7 parameters, but who cares? It's all being filled out by the IoC anyways.

Am I missing something here or is this basically correct?

+1  A: 

G'day George,

First off, what are the dependencies between the objects?

Lots of "isa" relationships? Lots of "hasa" relationships?

Lots of fan-in? Or fan-out?

George's response: "has-a mostly, been trying to follow the composition over inheritance advice...why would it matter though?"

As it's mostly "hasa" you should be all right.

Better make sure that your construction (and destruction) of the components is done correctly though to prevent memory leaks.

And, if this is in C++, make sure you use virtual destructors?

Rob Wells
has-a mostly, been trying to follow the composition over inheritance advice...why would it matter though?
George Mauer
Just looking at the nature of the coupling.
Rob Wells
C#, so we should be cool
George Mauer
+2  A: 

The need for many dependencies (maybe over 8) could be indicative of a design flaw but in general I think there is no problem as long as the design is cohesive.

Also, consider using a service locator or static gateway for infrastructure concerns such as logging and authorization rather than cluttering up the constructor arguments.

EDIT: 8 probably is too many but I figured there'd be the odd case for it. After looking at Lee's post I agree, 1-4 is usually good.

JC
+1  A: 

This is a tough one, and why I favor a hybrid approach where appropriate properties are mutable and only immutable properties and required dependencies without a useful default are part of the constructor. Some classes are constructed with the essentials, then tuned if necessary via setters.

erickson
+5  A: 

The relationship between class complexity and the size of the IoC constructor had not occurred to me before reading this question, but my analysis below suggests that having many arguments in the IoC constructor is a code smell to be aware of when using IoC. Having a goal to stick to a short constructor argument list will help you keep the classes themselves simple. Following the single responsibility principle will guide you towards this goal.

I work on a system that currently has 122 classes that are instantiated using the Spring.NET framework. All relationships between these classes are set up in their constructors. Admittedly, the system has its fair share of less than perfect code where I have broken a few rules. (But, hey, our failures are opportunities to learn!)

The constructors of those classes have varying numbers of arguments, which I show in the table below.

Number of constructor arguments    Number of classes
           0                             57
           1                             19
           2                             25
           3                              9
           4                              3
           5                              1
           6                              3
           7                              2
           8                              2

The classes with zero arguments are either concrete strategy classes, or classes that respond to events by sending data to external systems.

Those with 5 or 6 arguments are all somewhat inelegant and could use some refactoring to simplify them.

The four classes with 7 or 8 arguments are excellent examples of God objects. They ought to be broken up, and each is already on my list of trouble-spots within the system.

The remaining classes (1 to 4 arguments) are (mostly) simply designed, easy to understand, and conform to the single responsibility principle.

Lee
Nice answer - well documented, well written.
duffymo
A: 

It all depends upon what kind of container that you have used to do the IOC and what approaches the container takes whether it uses annotations or configuration file to saturate the object to be instiantiated. Furthermore, if your constructor parameters are just plain primitive data types then it is not really a big deal; however if you have non-primitive types then in my opinion, you can use the Property based DI rather than consutructor based DI.

Shiva