12

This is more of a nomenclature (technical writing) rather than a purely technical question. I am trying to write a refactoring proposal (and get it assigned to myself) centered around expanding dependency injection in our application. While we do use Spring for autowiring beans, there are still instances that instantiate beans using MyClass obj = new MyClass(...), which could totally be injected. I would like to make my proposal use elegant nomenclature and refer to the design pattern opposite of DI with a proper term.

Is "tight coupling" an adequate term that stands as an antonym to DI?

  • 1
    Yes, coupling describes both the act of using explicit class names in other classes and the resulting state of a code base. – Kilian Foth Sep 30 '16 at 14:33
  • 11
    No, tight coupling only describes the property of the resulting code, not the opposite of DI. You can use DI and still have tight coupling for completely different reasons. – Doc Brown Sep 30 '16 at 14:44
  • 1
    Agreed that DI and tight coupling are not opposites. – Eric King Sep 30 '16 at 19:16
  • @EricKing show off. +1 by the way. – candied_orange Sep 30 '16 at 21:51
  • 1
    "Dependency suction". – SeldomNeedy Oct 1 '16 at 4:13
30

No. Tight coupling is much more than what dependency injection deals with.

Dependency injection externalizes a decision of implementation. This goes a long way to decouple but coupling is more than just this.

A good antonym for dependency injection is hard coding a dependency. When you construct (use new or directly use some factory) inside a behavior object you've smushed together two different concerns. A service locator helps decouple but leaves you coupled to the service locator itself.

Coupling is more than just separating construction and behavior. If I have 101 methods that have to be called in some particular order from class A to class B I'm tightly coupled. Doesn't matter how wonderfully separated construction and behavior are.

Coupling is a measure the interdependence of the two objects. Anything that contributes to making it difficult to make changes in one without impacting the other is contributing to coupling. Dependency injection helps with this but it is not all of this.

  • Yes, hard coding (a dependency), as opposed to injecting it (at runtime) is exactly what I was going to suggest, too, you just were a little bit quicker than me. – Doc Brown Sep 30 '16 at 14:48
  • 7
    @DocBrown I sometimes wish this place didn't put so much emphasis on being fast. I'd like to hear how you'd put it. – candied_orange Sep 30 '16 at 14:50
  • Good answer - dependency injection does not imply decoupling. Believing otherwise leads down a bad road – Ant P Sep 30 '16 at 15:36
  • 1
    @CandiedOrange Maybe someone should suggest in meta that answers be remain hidden for a period of time. And/Or that votes be hidden from public view for N hours... Or until an answer is selected. I know I'm not entirely objective when one answer already has 10 votes and the other 5 answers have none! – svidgen Sep 30 '16 at 15:45
  • 1
    @svidgen search "fastest gun in the west" on meta. The issue already has a long history. – candied_orange Sep 30 '16 at 15:48
6

Strictly speaking, Dependency Injection only really opposes NOT Dependency Injection -- and therefore any dependency management strategy that isn't Dependency Injection.

[Unwanted] coupling, though not exactly an orthogonal issue, can either occur or be mitigated either way. These are both coupled to DependencyClass:

public DependencyInjectedConstructor(DependencyClass dep) {
  dep.do();
}

public DependencyLookupConstructor() {
  var dep = new DependencyClass();
  dep.do();
}

DependencyLookupConstructor is coupled to a particular DependencyClass in this case. But, they're both coupled to DependencyClass. The real evil, if there is one here, isn't the coupling necessarily, it's that DependencyLookupConstructor needs to change if DependencyClass suddenly needs its own dependencies injected1.

However, this constructor/class is even more loosely coupled:

public DependencyLocatingConstructor() {
  var dep = ServiceLocator.GetMyDoer();
  dep.do();
}

If you're working in C#, the above will permit your ServiceLocator to return anything when GetMyDoer() is invoked, as long as it has can do() what DependencyLocatingConstructor has it do(). You get the benefit of compile-time signature validation without even being coupled to a complete interface2.

So, pick your poison.

But basically, if there's a concrete "opposite" of Dependency Injection, it would be something else in the realm of "Dependency Management Strategies." Amongst others, if you used any of the following in conversation, I'd recognize it as being NOT Dependency Injection:

  • Service Locator Pattern
  • Dependency Locator / Location
  • Direct object/dependency construction
  • Hidden dependency
  • "Not Dependency Injection"

1. Ironically, some of the problems that DI solves at higher levels are sort of a result of [over-]using DI in the lower levels. I've had the pleasure of working on codebases with unnecessary complexity all over as a result of accommodating the handful of places where that complexity actually helped ... I'm admittedly biased by bad exposure.

2. Using service location also permits you to easily specify different dependencies of the same type by their functional role from the invoking code, while still being largely agnostic about how the dependency is built. Suppose you need to resolve User or IUser for different purposes: E.g., Locator.GetAdministrator() versus Locator.GetAuthor() -- or whatever. My code can ask for what it needs functionally without even knowing what interfaces it supports.

  • 2
    The salvation for DependencyInjectedConstructor(DependencyClass dep) is that DependencyClass could be an interface or abstract class. This is why it makes me sad that C# coders use an interface prefix, as in IDependency. As the client, It's really not my business what this Dependency thing is. As long as I don't construct it, all I have to know is how to talk to it. What it is is someone else's problem. – candied_orange Sep 30 '16 at 17:25
  • Points being, DI still couples you to that interface, and it doesn't require that DependencyClass be an abstract interface at all. It only requires that the construction/configuration/location logic existing "somewhere else." ... Well, and more pertinently to the question, the point is that DI isn't "the opposite of tight coupling" :) – svidgen Sep 30 '16 at 17:38
  • Actually ... I may be slightly out of bounds in saying DI necessarily couples you to an interface, even in C#. Though, I've avoided them in C#, I'm under the impression I could also accept dynamic parameters. (But not var parameters, if memory serves.) So, with DI in C#, I think I either have to code against an interface, or I have to totally forgo the compile-time validation. – svidgen Sep 30 '16 at 17:41
  • Objects are coupled to the interfaces. Whether you use the interface keyword or not. That's what a proper interface is. Everything you HAVE to be coupled to. What you boil away are implementation details and extra stuff you don't need. We can formalize this by using the interface keyword to let the client tell the world, "All I need is this". But we don't have to. Heck we can do duck typing, well in some languages. – candied_orange Sep 30 '16 at 17:50
  • I'm not sure we're in total disagreement. But, to clarify ... Objects are internally coupled to their own interfaces, yes. But, the interface itself only imposes dependency-coupling if the interface is explicitly named. In C#, using dynamic or var and getting an object from a locator let's you ignore the interface and use any class that can do() what you need, regardless of whether that class implements some IDoer interface. In other words, if we have A->B<-C, DI decouples A from C, but it requires both A and C to be coupled to B, and prevents use of D, even if D will do(). – svidgen Sep 30 '16 at 18:32
0

I would go with dependency encapsulation. This expresses the dependency is locked in rather than visiting and leaving again.

0

I don't know that there's specific, widely accepted industry terminology, but alternatives that come to mind include internal instance creation, internal dependency creation, local dependencies, or locally scoped dependencies.

  • 2
    i like instance creation but it is not specific enough. DI creates instances but by the means of controller and not at the application level. maybe internal instance creation – amphibient Sep 30 '16 at 14:41

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.