Timeline for Is it good design to have one constructor that supplies a "default" concrete class to another that takes an abstraction?
Current License: CC BY-SA 4.0
10 events
when toggle format | what | by | license | comment | |
---|---|---|---|---|---|
Jan 31, 2020 at 6:58 | comment | added | casablanca | The additional default constructor is effectively a factory method and that is most certainly not an anti-pattern. And given that the OP already has a compile-time dependency on the concrete strategy, there is no practical benefit to pulling this factory method out into its own class (it is certainly possible and easy to pull it out if the need arises, and enabling change is the driving force behind design principles). | |
Jan 30, 2020 at 21:49 | comment | added | Filip Milovanović | @RyanPalmer & David Arno: I'm a bit on the fence with this one; having just a default constructor makes the application inflexible, but having another one that lets you replace the dependencies removes that issue. It's true, however, that you have to drag the hidden dependency along, which is why you don't want to reference something from a different module. The final issue that requires some deliberation is that having multiple constructors may potentially work less smoothly with some DI-containers; on the other hand, code should not depend on the container. | |
Jan 30, 2020 at 18:05 | comment | added | Ryan Palmer | I read the other answer you shared, and the author states: "The way this wouldn’t be Bastard Injection would be that all these classes live within the same module." In my case, this is true. The architectural boundary between Feature and DefaultConcreteStrategy is just at the source code level, but they live in the same module. (Same Java package, same JAR file.) Is it still the Bastard Injection Pattern? The author of that book referenced in his question also made the same statement. | |
Jan 30, 2020 at 14:52 | comment | added | Rotem | I think I see my answer in the article : "This approach makes the application inflexible since replacing, wrapping or intercepting any of the given dependencies can lead to sweeping changes throughout the application. " | |
Jan 30, 2020 at 14:41 | comment | added | Rotem | @David I would make the argument that a default constructor with a concrete type immediately reduced to an interface is not the same as a direct member reference on the concrete type. A change in the concrete type without a change to the interface has no effect on the referencing class. Would love to see a counterexample. | |
Jan 30, 2020 at 13:23 | comment | added | David Arno | @Rotem, adding a default constructor to a type, which then handles its own dependencies, results in direct coupling within that type. This is a basic violation of the dependency inversion principle. I'd suggest that explaining that principle and how to violate it is beyond the scope of an answer to this question. But I'm happy to expand my answer if you think this would be useful. | |
Jan 30, 2020 at 13:19 | comment | added | David Arno | @Blake, indeed. That's the meaning I'd always associated with it too. Some people use(d) the term to refer to bastard injection though. That's why I prefer "pure DI" as it avoids that confusion. | |
Jan 30, 2020 at 13:14 | comment | added | Rotem | Both your answer and the linked article talk a lot about 'violating the principle' but don't really explain what practical negative side effect this has. | |
Jan 30, 2020 at 12:43 | comment | added | Blake | I think "poor man's DI" is different from Bastard Injection. I've always understood "poor man's DI" as just doing Dependency Injection without using a fancy IOC Container. | |
Jan 30, 2020 at 10:34 | history | answered | David Arno | CC BY-SA 4.0 |