Revisiting the Strategy pattern
In this section, we'll leverage the Strategy pattern to compose complex object trees and use DI to dynamically create those instances without using the new
keyword, moving away from being control freaks and toward writing DI-ready code.
The Strategy pattern is a behavioral design pattern that we can use to compose object trees at runtime, allowing extra flexibility and control over objects' behavior. Composing our objects using the Strategy pattern should make our classes easier to test and maintain, as well as putting us on a SOLID path.
From now on, we want to compose objects and lower the amount of inheritance to a minimum. We call that principle composition over inheritance. The goal is to inject dependencies (composition) into the current class instead of depending on base class features (inheritance). Moreover, that allows behaviors to be extracted in external classes (SRP/ISP), then reused in one or more other classes (composition...