My Control Class basically picks which object / class to instantiate. Because this is basically what it does it naturally has many objects / classes it calls.
If I use dependency injection I will be injecting all of these objects. This seems bad for two reasons.
-
I’ve heard that about 3 dependent objects / classes is normal to KISS ( Keep it Simple Smarty)
-
Only one of the objects / classes will be used. So in a sense the others are instantiated for no reason.
How do I resolve these design considerations to satisfy – decoupled code, but simple and used code?
What you do is that you actually map some parameter onto some functionality, a so called script or action.
So in the end you only need a convention how to map that parameter or name onto some function. As functions can be somewhere (in some other object, in the global space, anonymous), you don’t really need to inject many objects into your control class, but functions and the mapping.
If you would than even add some more differentiation with function name and parameters (or “modules” and “actions”), well then, you could drastically reduce your code and you can actually make the request inject the dependency:
Script or Action
This pseudo-code shows the actual business of your control class: Call some functions based on it’s input. The concrete dependencies are:
ObjectMakerSession$mapAs session is static, you should replace it with something that actually can be injected.
As
$mapis an array, it can be injected, but the logic of the mapping might need to become something more internal, so if$mapis anArrayAccess, this can happen already.The non-concrete dependencies are hidden inside the actual
$ajax_type, so these dependencies are dependent on that parameter through mapping, which is already a dependency. So the last dependency is:$ajax_typeThis dependency is related to both the control class and the mapping. So the control class itself could be made a dependency to the ajax type as well. But as you use a static global function, I’ll simplify this inside a class function so actually dependencies can be passed into it. I put the factory into a global function and the ajax types are loaded from an ini-file:
Ini file:
To have this work, this needs some stubs for mocking, which is easy with your example:
Those are enough to run the code above which will give:
The ajax types:
And the ajax controler:
This is just exemplary. There is no guarantee that this fits as a design for your needs, just for demonstrating purposes. What it shows is that your actual controller function is not normalized / modular enough. When you better analyze the dependencies that exist and you inject them instead that you hardencode them, you will automatically find the best way to design your system.
What this example shows as well is that you have a tons of hidden dependencies for the request and response. You really need to draw lines somewhere and define what you pass through and in which direction. Say goodbye to global static state. Always inject. You can even start with function that need everything as parameters if it helps.