I agree it is mildly amusing to watch Javascript devs excitedly discover these principles but it does show that these principles are universal. Virtually everything in this talk applies to building very large Java and C++ applications. (And here I don't mean 10mb... rather global systems made up of dozens of services and hundreds of components.) All of this is about modularity -- of configuration, of state, of logic, and of concerns.
I think what he's pushing is slightly different from dependency injection.
For one, one of the hallmarks of DI is that you should have a single, central location where all your dependencies are assembled. Whereas one of the slides in the talk is, "Avoid central configuration at all cost." His concrete example is with CSS files, but I could definitely a similar principal applying to your "composition.json" file in a large DI application.
It seems more to me like he's talking about the opposite of DI. It's a possible solution to how you decouple modules from their dependencies. But in DI, you accomplish it by having a central orchestrator inject the dependencies into your modules. In this "enhance" mechanism, by contrast, you reject that central orchestration, and instead have dependencies independently injecting themselves into the modules.
> one of the hallmarks of DI is that you should have a single, central location where all your dependencies are assembled.
This is very interesting to me mainly because it's the first time I've heard it. In Martin Fowler's bliki article [0] he discusses having an assembler, but for me that's just an abstract factory pattern (perhaps I'm wrong). If you don't have abstract dependencies, then you don't need it. Do you have some sources which discuss this? I don't really see the advantage of using a kind of repository for dependencies.
As for how this fits with abstract factories, in DI they exist to handle a specific problem: sometimes (but not always), actual instance construction has to be delayed until the last minute. But you still want things to be loosely coupled, and do the wire-up at the same place where you handle all the other object composition. So you do that by declaring an abstract factory, and then generating its concrete implementation at wire-up time. That way the details of the composition are still being injected, even if they're being executed at the site where they'll be consumed.
Enhance kind of looks like google hype. Essentially it’s a way of dynamic dependency discovery. Rather than explicitly adding imports, you just crawl through a directory convention and discover things to bundle and connect.
I liked the talk, dependency management and code splitting are big problems in large apps, but there was a lot of hand wavy “we at google invented this, so it must be great” reasoning.
>For one, one of the hallmarks of DI is that you should have a single, central location where all your dependencies are assembled
While this is true, if you're doing your composition root right in a large application, then you're assembling most of your dependency graph using conventions, and assembling only the most unique things by hand.
While it may be a hallmark of DI it’s not necessary. Spring is perhaps the most famous DI framework of them all and is frequently used by “classpath scanning” relevant components to wire in
There was denial for a long time that IOC containers and dependency injection added zero value due to the module system and imports. There are a few nice options out there now, like inversify and typedi. I think TypeScript has been attracted a different crowd with a different taste for whats good. I'm pretty happy about that.
Ruby went through this exact same thing. I think Sandi Metz's book was a turning point for the community.
Well one way you avoid the need for DI is that if you are only using DI to allow you to swap out real collaborators for fakes in your tests ... to instead simply mock module imports in your tests, (to mock those collaborators). This is common with Jest in the React world. And it's easy with a good module system.
I'm building 2 large apps, with no DI, and using this approach (Jest) and I never want to use DI again. I hated the DI system in Angular 2+
Maybe I misunderstand DI when I want to have a "stateful" module, let's say a class that I export that requires some config input (think Database). I initiate it in index.js or something and then just pass it in the constructor in every other class that needs to use it. What is this called? If it's DI, how do I do that with modules only?
The reason I'm asking is because sometimes I want that dependency 10 steps deep and if the 10th class wants to use it I need to pass it through all other 10 classes. Creates a lot of bloat.
Yes, that is DI too, you can think of it something like 'injecting a shared singleton service', and yes the passing into a constructor is the basic approach you might call 'manual DI'.
And yep modules can let you avoid the need for that, you can share singletons by exporting an instance from a module, and then if you import that module from 2 other modules, both will get the same instance [1].
Though tbh that still feels a bit gross to me :) There are other solutions (like the context API [2] in React for passing some data/instance to multiple components at different levels in your 'component tree').
Is there a single place to learn about all of the common software engineering principles, as opposed to rediscovering universal principles over and over again?
Short answer: No, but your best bet might be to read old, substantial books, and find other work by the kind of people who read and wrote those books before they were old.
Longer answer: Basically, you need to get away from the world of front-end web development, and from the echo chamber blog posts and conference talks by people who have only ever worked in that area. No-one is writing anything large, high-performance, high-reliability or long-lived there yet, so you need to look for experience from people who have had to do those things in other contexts instead.
Classic books like Code Complete and The Pragmatic Programmer, early "serious OO" books like Design Patterns, and practical advice books of a similar generation in the Effective <programming language> style all contain a wealth of knowledge and insightful commentary. Of course some of the technical details are quite dated today and some of the specific techniques discussed might no longer be considered good practice a decade or two later, but many of the underlying principles and the discussions around them are as relevant as ever. A bit more recently, there were interesting discussions about a broad range of programming issues in Beautiful Code and the related titles, and there have been some interesting case studies based on open source software too.
If you want to read some shorter pieces online, I recommend finding a few authors who work in fields like games or embedded software, where there are often significant performance and reliability constraints to deal with, not to mention hard deadlines that force difficult decisions and compromises. There are some healthy doses of reality in there that you won't find in less demanding environments.
Enterprise applications, while often considered bland, can also be large and some of the longest-lived software we develop, and much has been written about organising and maintaining them, including real-world pressures like changing operating environments and large development teams whose members come and go. Perhaps a little ironically, this now includes a fair bit of back-end web development. Some of the writing around this is well worth a read as well, but beware that this part of the industry is plagued by consultants who talk a good talk but don't have much of a track record or other evidence to back up their advice. Approach with caution, particularly anyone who uses words like "agile", "lean", "craftsmanship" and anything else on the buzzword scale.
In a way it's not so much rediscovering the principles themselves as discovering something about the ways that "pain points" in a language have changed over time... Such that the techniques' benefits begin to visibly outweigh their cost.
In all those books from the many "What books would you recommend every programmer read?" questions on HN, Stack Overflow, and every other forum developers gather.
EDIT: You said single place, sorry.. Safari books online, Codeproject, and MSDN are potential candidates.
Agreed again. We've been debating the merits of jazz vs. orchestra models for larger systems since at least when OO started getting popular, say back in the early '90s, and probably much longer by one name or another. This is basic software architecture stuff, though sadly in today's framework-heavy front-end world, a lot of that basic knowledge isn't as widespread as it usefully could be.
I agree it is mildly amusing to watch Javascript devs excitedly discover these principles but it does show that these principles are universal. Virtually everything in this talk applies to building very large Java and C++ applications. (And here I don't mean 10mb... rather global systems made up of dozens of services and hundreds of components.) All of this is about modularity -- of configuration, of state, of logic, and of concerns.