3 ms·
This post is too abstract and neither offers a good explanation of a problem nor suggests an alternative solution. The task of dependency injection appears rig
by ivan_gammel 13y ago
This post is too abstract and neither offers a good explanation of a problem nor suggests an alternative solution.
The task of dependency injection appears right after the decomposition of a problem: you cannot avoid it, so you either do it manually by constructing and wiring all necessary objects (self-managed singleton anti-pattern is quite common here, let his fathers burn in hell) or using a DI container. Unless you want to invent your own bicycle with poker and curvy girls (which may make sense in very specific cases, but not in general), you will use Spring, Guice or CDI.
How to choose the right solution? It always depends on requirements, not on generic concepts from theory of OOD. In small project you can follow KISS principle by sacrificing decoupling and wiring objects manually. In bigger one you always need to look at the other libraries and environment you are going to use. If it's a JEE container (a modern one, compatible with latest specs), your choice can be CDI. If you are going to work with GWT, it's Guice (it's the best for programmatic configuration, but lacks some features). In all other cases Spring 4 is the best option.
What's wrong with the talk about reuse vs decoupling? The author addresses the problem of sustainability of a system to changes by rejecting the core concept of OOD - the reuse - and avoiding the use of DI, just to avoid some hypothetic bug in implementation module. However, our industry developed a lot of tools and best practices to address such problems when writing reusable code: unit tests, SOLID (SRP is my favorite one), incremental compilers and smart IDEs. Avoiding reuse is like not using electricity if you afraid of fire.
- sitkack 13y agoThis was an excellent post, it was abstract but at least he kept it short. I had an argument about DI with a friend months ago and it boiled down in his use (Guice) that it was only for testing components. I think of DI as a big meta-constructor in the sky, it gives dynamic scope to a lexically scoped language. And the problem with it as we currently use it, is that it hides intent behind a config file so we can't read what the code is actually doing, only doing abstractly. What if the tooling ghosted those abstract classes and put the concrete classes in their place with reading and navigating? It could effectively "statically link" in the IDE those dependencies.
- ivan_gammel 13y agoIn good design the intent is clearly defined in interface on which you depend. If the code has side effects, if it does something not specified by interface, if it has more than one role, this code needs to be fixed and it is not a problem with DI. It's a problem with your design. As I already said, you always need to wire your objects. You do it, possibly, without realizing it, but you still do it. If you reject the idea of DI just because the code is bad and DI is "Not Invented Here", you will not do the wiring better. Writting custom DI is hard, and it's very likely that you will end with unmaintainable nightmare that needs to be rewritten completely. For 15 years I've seen this nightmare too much and never seen the successful projects with custom DI.
- sitkack 13y agoSo is DI a result of incomplete language design? Should the concept of DI be baked in?
- ivan_gammel 13y agoFor enterprise software, for large projects, probably, yes. Together with more advanced reflection (I imagine MOF/EMF as a native part of Java) to allow meta-programming and smarter code generation.
- cstejerean 13y agoMy tools already do that. With IntelliJ and its Spring support I can easily jump directly to the actual implementation that is being wired in, just as easily as I would jump to source if it was a concrete class. But in a properly designed system I rarely need to go poking into the implementations of my dependencies.