Alex Rivera | Logout

Going bananas with loose coupling and dependency injection

Asked 2009-01-09T10:45:32.773
17

With the latest additions to our dependency injection framework (annotations in spring), the marginal cost of creating DI-managed components seems to have hit some critical new threshold. While there previously was an overhead associated with spring (tons of XML and additional indirections), dependency injection seems to have started going where lots of patterns go; they go under the hood and "disappear".

The consequence of this is that the conceptual overhead associated with a large number of components becomes acceptable. It's arguable that we could make a system where most classes only expose one single public method and build the whole system by just aggregating these pieces like crazy. In our case a few things are given; the user interface of your application has some functional requirements that shape the topmost services. And the back-end systems control the lower part. But in between these two, everything is up for grabs.

Our constant discussion is really why are we grouping things in classes and what should the principles be ? A couple of things are certain; the facade pattern is dead and buried. Any service containing multiple unrelated features also tend to get split up. "Unrelated feature" is interpreted in an extremely much stricter sense than I have ever done earlier.

In our team there are two prevailing trains of thought here: Implementation dependencies restrict grouping; any functionality in a single class should preferably be a client of all injected dependencies. We are a DDD project and the other fraction thinks the domain restricts grouping (CustomerService or finer grained CustomerProductService, CustomerOrderService) - normalized usage of injected dependencies is unimportant.

So in the loosely coupled DI universe, why are we grouping logic in classes ?

edit: duffymo point out that this may be

Edit
Report

1 Answer

4
  • Why are we grouping things in classes and what should the principles be ?

Are you stressing the, "Grouping," or the, "Classes?"

If you're asking why are we grouping things, then I'd second Medelt's, "Maintainability," though I'd rephrase it as, "To reduce the potential cost of ripple effects."

Consider, for a moment, not the actual coupling between your components (classes, files, whatever they may be) but the potential coupling, that is, the maximum possible number of source code dependencies between those components.

There is a theorem which shows that, given a chain of components a - b - c - d - e, such that a depends on b, etc., the probability that changing e will then change the c component cannot be greater than the possibility that changing e will then change d. And in real software systems, the probability that changing e will affect c is usually less than the probability that changing e will affect d.

Of course, you might say, that's obvious. But we can make it even more obvious. In this example, d has a direct dependency on e, and c has an indirect (via d) dependency on e. Thus we can say that, statistically, a system formed predominantly of direct dependencies will suffer from a greater ripple effect than a system formed predominantly from indirect dependencies.

Given that, in the real world, each ripple effect costs money, we can say that the cost of ripple effect of an update to system formed predominantly of direct dependencies will be higher than the cost of ripple effect of an update to system formed predominantly of indirect dependencies.

Now, back to potential coupling. It's possible to show that, within an absolute encapsulation context (such as Java or C#, where recursive encapsulation is not widely employed) all components are potentially connected to one another via either a direct dependency or an indirect dependency with a single, intermediate component. Statistically, a

answered 2009-11-27T06:59:54.423

Your Answer