I am trying to write code that uses Dependency Injection to allow mockery and have a cleaner, more explicit design.
I often encounter a specific problem that I thought was common, but I have not yet found anything on the network that helped me overcome it.
The problem is that object A depends on B, B depends on C, C depends on D, etc. in a chain that can have many links.
It seems that for the practical implementation of injections for treatment here, A will have to ask B, C, D, etc. in its constructor (or BFactory, CFactory, etc. for objects that create instances on which they depend), I assume for argument that dependencies are not optional or not specified for specific methods, which makes the installer inject or parameter inject unsuitable method.
This tells me that long chains of dependent objects are antipatterns. In an abstract sense, this has something in common with the antispatter arrows. Long chains of dependent objects form an arrow-shaped sequence diagram.
Perhaps then I should avoid this practice and follow the recommendations in Zen of Python that "flat is better than nested." This involves a construction in which the main program creates two or three objects that interact and produce a result that is returned to the main program, and then creates two or three more for the next stage of work, etc.
I have the feeling that such code is easy to understand and debug, as well as simplify dependency injection. But it seems that this contradicts the Tell Do not Ask principle and makes the main program too thick. I like the idea that the core is so small and so obvious that it does not require unit testing. And “Tell me not to ask” tells me that if everything starts with A and ends with A, then this is Responsibility. Assume that A is the customer who is billed, and the customer owns the data necessary to start the billing process, as well as the email address that must be sent at the end at the end. Then it seems that A should do the work itself (the main one can simply call Customer.billYourself ()) instead of transferring responsibility to the main one by providing the main heap of invoices and an email address.
So, should you avoid dependency chains, make DIs easier, or hug them because of Tell Do not Ask?