Search code examples
ooplanguage-agnosticdependency-injectionloose-coupling

How to understand the big picture in a loose coupled application?


We have been developing code using loose coupling and dependency injection.

A lot of "service" style classes have a constructor and one method that implements an interface. Each individual class is very easy to understand in isolation.

However, because of the looseness of the coupling, looking at a class tells you nothing about the classes around it or where it fits in the larger picture.

It's not easy to jump to collaborators using Eclipse because you have to go via the interfaces. If the interface is Runnable, that is no help in finding which class is actually plugged in. Really it's necessary to go back to the DI container definition and try to figure things out from there.

Here's a line of code from a dependency injected service class:-

  // myExpiryCutoffDateService was injected, 
  Date cutoff = myExpiryCutoffDateService.get();

Coupling here is as loose as can be. The expiry date be implemented literally in any manner.

Here's what it might look like in a more coupled application.

  ExpiryDateService = new ExpiryDateService();
  Date cutoff = getCutoffDate( databaseConnection, paymentInstrument );

From the tightly coupled version, I can infer that the cutoff date is somehow determined from the payment instrument using a database connection.

I'm finding code of the first style harder to understand than code of the second style.

You might argue that when reading this class, I don't need to know how the cutoff date is figured out. That's true, but if I'm narrowing in on a bug or working out where an enhancement needs to slot in, that is useful information to know.

Is anyone else experiencing this problem? What solutions have you? Is this just something to adjust to? Are there any tools to allow visualisation of the way classes are wired together? Should I make the classes bigger or more coupled?

(Have deliberately left this question container-agnostic as I'm interested in answers for any).


Solution

  • While I don't know how to answer this question in a single paragraph, I attempted to answer it in a blog post instead: http://blog.ploeh.dk/2012/02/02/LooseCouplingAndTheBigPicture.aspx

    To summarize, I find that the most important points are:

    • Understanding a loosely coupled code base requires a different mindset. While it's harder to 'jump to collaborators' it should also be more or less irrelevant.
    • Loose coupling is all about understanding a part without understanding the whole. You should rarely need to understand it all at the same time.
    • When zeroing in on a bug, you should rely on stack traces rather than the static structure of the code in order to learn about collaborators.
    • It's the responsibility of the developers writing the code to make sure that it's easy to understand - it's not the responsibility of the developer reading the code.