Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Dependency inversion and pervasive dependencies

I'm trying to get dependency inversion, or at least understand how to apply it, but the problem I have at the moment is how to deal with dependencies that are pervasive. The classic example of this is trace logging, but in my application I have many services that most if not all code will depend on (trace logging, string manipulation, user message logging etc).

None of the solutions to this would appear to be particularly palatable:

  • Using constructor dependency injection would mean that most of the constructors would have several, many, standard injected dependencies because most classes explicitly require those dependencies (they are not just passing them down to objects that they construct).
  • Service locator pattern just drives the dependencies underground, removing them from the constructor but hiding them so that it's not even explicit that the dependencies are required
  • Singleton services are, well, Singletons, and also serve to hide the dependencies
  • Lumping all those common services together into a single CommonServices interface and injecting that aswell a) violates the Law of Demeter and b) is really just another name for a Service Locator, albeit a specific rather than a generic one.

Does anyone have any other suggestions for how to structure these kinds of dependencies, or indeed any experience of any of the above solutions?

Note that I don't have a particular DI framework in mind, in fact we're programming in C++ and would be doing any injection manually (if indeed dependencies are injected).

like image 798
Tom Quarendon Avatar asked Oct 24 '12 20:10

Tom Quarendon


People also ask

What is difference between dependency inversion and dependency?

Dependency Injection is an implementation technique for populating instance variables of a class. Dependency Inversion is a general design guideline which recommends that classes should only have direct relationships with high-level abstractions.

What is the meaning of dependency inversion?

The Dependency Inversion Principle (DIP) states that high level modules should not depend on low level modules; both should depend on abstractions. Abstractions should not depend on details.

What is an example of dependency inversion principle?

In our example, CustomerBusinessLogic depends on the DataAccess class, so CustomerBusinessLogic is a high-level module and DataAccess is a low-level module. So, as per the first rule of DIP, CustomerBusinessLogic should not depend on the concrete DataAccess class, instead both classes should depend on abstraction.

What is explicit and implicit dependency?

These dependencies are implicit if they exist only in the code within your class, and not in its public interface. Explicit dependencies appear most often in an object's constructor, for class-level dependencies, or in a particular method's parameter list, for more local dependencies.


1 Answers

Service locator pattern just drives the dependencies underground, Singleton services are, well, Singletons, and also serve to hide the dependencies

This is a good observation. Hiding the dependencies doesn't remove them. Instead you should address the number of dependencies a class needs.

Using constructor dependency injection would mean that most of the constructors would have several, many, standard injected dependencies because most classes explicitly require those dependencies

If this is the case, you are probably violating the Single Responsibility Principle. In other words, those classes are probably too big and do too much. Since you are talking about logging and tracing, you should ask yourself if you aren't logging too much. But in general, logging and tracing are cross-cutting concerns and you should not have to add them to many classes in the system. If you correctly apply the SOLID principles, this problem goes away (as explained here).

like image 82
Steven Avatar answered Oct 23 '22 04:10

Steven