I’m writing some code which I’ve placed into a separate util class. The logic in itself is clear, but it is dependent on some values in $settings. I’m sort of torn between the following alternatives:
public static function someUtilFunc ($settings, $param1, $param2, ...)
{
if ($settings['someValue']) {
doSomething();
}
}
vs
public static function someUtilFunc ($param1, $param2, ...)
{
global $app;
$container = $app->getContainer ();
$settings = $container->get ('settings');
if ($settings['someValue']) {
doSomething();
}
}
vs
public static function someUtilFunc ($param1, $param2, ...)
{
$settings = SomeUtilClass::getSettings();
if ($settings['someValue']) {
doSomething();
}
}
Option 1 is clearer in the sense that the $settings parameter makes it clear that $settings is to be used. On the other hand, this requires me to pass $settings parameter from any invocation which is sort of unnecessary since the next 2 options present an alternative to this.
Option 2 is IMHO better since it decouples the $settings from the function parameter list.
Option 3 is my favorite since it wraps the reference to “global $app” into a function; should this change in the future all the code using this can be adapted by simple changing this central function.
Does anybody have an opinion (or a better idea) on what best practice is here?
Thank you in advance.
Talking about design;
I would always go for injection. Looking at your first example; do you need to pass in the entire $settings
? Or should is just be a specific value. Makes it more explicit what the util needs instead of relying on array keys being present (or not).
If passing the values as separate arguments results in too many arguments or being too verbose in usage since you are repeating yourself by passing in the same arguments again and again, maybe the utility needs to have a state (so you can inject the settings upfront).
If you give it a state maybe the choice of making it a static method should also be reconsidered.
All design choices, nothing is really good or bad. It really depends on the situation.
Going back to your proposals. for me the 2nd and 3rd would not be an option, so I would pick the first, but certainly think about the points I made above.
1 Like
Thank you for your advice, I’m not trying argue, just trying to understand.
Is the 3rd option not a ‘sort-of-injection’ where the injection happens through a function call in the code rather than an earlier assignment to a container variable?
Your comment about preferring injection is appreciated, it may just be easier to assign this in dependencies.php and then reference the instance created at that point.
Thank you.
Me neither, just trying to give advice
The 3rd example is not injection. The setting is not injected, the util is searching for the settings in some global place. This results in the util depending on the SomeUtilClass
. If you ever need to change the settings in a single place you will not be able to.
Especially in unit testing you will benefit from injection.
Maybe it will be interesting for you to read some articles about IoC (inversion of control), DI (Dependency Injection) and the SL (Service Locator).
I get your point, thank you. Injection it will be.