简体   繁体   中英

Php, Dependency Injection - kills static methods, but instatize is unnecessary

here is a basic class-construction, before using DI (I know, its a bit incorrect structure, please just try to focus on the problem)

class Mobile
{
    public function getWeight()
    {
        return 4;
    }
}

class User
{
    public static function getWeight()
    {
        $mobile = new Mobile();
        return $mobile->getWeight();
    }
}

after a renew, using DI:

class User
{
    public $mobile;

    public function getWeight()
    {
        return $this->mobile->getWeight();
    }
}

If we check, using the getWeight() didn't demand to have an instance of User since it was static - its pointless to create an instance of it. But now, getWeight() cant be static, so an instance is needed anyway - just because of dependency injection! Of course, I know this example is a bit limp - I just want to point out the logic that dependency injection kills static method, but sometimes static methods need, because its pointless to have an instance of a class, just think of JAVA Math.max() method. How to work it around?

Yes, dependency injection makes static methods unnecessary, but the reason you don't see it is because your example is badly chosen.

There is still a use for static methods. But they should not be used beyond the construction root point in an application.

What's this construction root? Every application starts in a static, global world. There is the request info in $_SERVER, $_GET and $_POST, there is a requested URL, which is either processed in a central file, or even pointing to the respective script files.

And then we have the implementation of models, business logic, utility objects for form validation, templating etc. - and if done well, these all have no static methods, but all require to be instantiated.

Which is no problem, because they all get instantiated - possibly with the help of a dependency injection container. So the construction root is where the instance world of good objects meet the static global world of every request. And it is a good practice to pinpoint the exact layer where this meeting takes place, ie there should be no static calls beyond that point.

In essence: If you are able to use a DI container, you will configure it in the static global world, and then, probably in the controller, ask it for an object. And this will create all needed sub objects, inject them all into each other as needed, and return to you only one instance of the main object you requested. And you do not need to worry about how to inject all these other objects - they are already there.

As a final remark: Why are static calls bad? Because they statically link this call with the class that is used. You cannot simply replace this call with another class just by passing a different object implementing the same interface or inheriting from the same parent object. You'd have to change the code.

And your example of Java's Math.max() is a different situation. In PHP this wouldn't even be an object, but only a global function. And it works because this function does not work with any instances of objects - the input data unambiguously defines the output of the function.

But don't make the mistake of defining every method you create that only works on input parameters and returns an output as static. If you have an object, enjoy it. :)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM