7 ms·
100% this. Having worked on projects using and not using DI in several languages, I'd prefer a world in which we just say no to DI. What it offers, relative to
by NewMountain 4y ago
100% this. Having worked on projects using and not using DI in several languages, I'd prefer a world in which we just say no to DI. What it offers, relative to the indirection and cognitive overhead has almost always been net negative.
- tored 4y agoHow is DI a cognitive overhead?
- mkl95 4y agoOP mentioned Python, and I agree that it's a cognitive overhead in that particular case, in the sense that it's an abstraction that can be avoided. If you are using something like Java or C++ then it's easy to see the benefits (some C++ developers would disagree though, read https://accu.org/journals/overload/25/140/pamudurthy_2403/ https://accu.org/journals/overload/25/140/pamudurthy_2403/).
- pydry 4y agoThe extra levels of indirection mean more code. Python programs are about 30-40% shorter than Java equivalents. More code = more cognitive overhead
- ivanche 4y agoWhat do you suggest instead? new operators everywhere? Service Locator? Global Singletons everywhere? Honestly, I don't know how you came from "my object needs objects A, B, and C to work" to the "it's cognitive overload". Your object still needs A, B and C to work, just with any other approach it's implicit which is spooky action at a distance in its finest and way more cognitive load.
- garethrowlands 4y agoThe answer is that your "composition root" constructs the objects using normal code. Usually the composition root is the `main` function. def main: a = ... b = ... c = ... my_object = MyObject(a,b,c) my_object.do_something() If you think it's ugly in `main`, then extract to another function: def main: my_object = make_my_object() # constructs my_object as above my_object.do_something() I've used this pattern extensively in Kotlin and also php (ew). It works well in pretty much any language.
- ivanche 4y agoI agree with you completely! As the matter of fact, I prefer this approach. But that is dependency injection at its finest, and something that NewMountain above said is "cognitive overhead" and "indirection".
- rodelrod 4y agoI can't speak for NewMountain but I assume he was talking about using a DI framework or container (e.g. Spring) where dependencies are defined declaratively and the framework handles the instantiation. This is what brings the indirection and the cognitive overhead.
- necovek 4y agoIf a, b and c are MyObject's "dependencies", that's dependency injection. If MyObject has no other dependencies (produces no side effects other than on a/b/c), it is fully dependency injected. Magic, monkey-patching mess of dependency injection libraries is terrible. Dependency injection as a concept is simple functional approach to imperative and OO programming.
- KronisLV 4y ago> my_object = MyObject(a,b,c) > If a, b and c are MyObject's "dependencies", that's dependency injection. In practice, though, at least coming from a Java/.NET background, DI would be understood as using something like a decorator/annotation/some registration mechanism to let the framework handle giving you a valid instance of the class that you're after, rather than straight up using the constructor whilst filling out the parameters manually. While your example is technically true, it wouldn't be the answer that anyone in a programming interview (at least for those languages) might expect you to provide as an example. That said, adopting the composition root approach in a Java project (or using a god-object for all of the services) was oddly liberating and felt way more simple than mucking about with appeasing Spring's @Autowired annotation and its finnicky nature.
- jseban 4y agoI agree, here's a presentation from a guy who went full circle in Ruby: https://www.youtube.com/watch?v=ewIbYQ-QuC0&ab_channel=Confreaks https://www.youtube.com/watch?v=ewIbYQ-QuC0&ab_channel=Confr...