Php,依赖注入 - 杀死静态方法,但实例化是不必要的

Joh*_*ith 3 php dependency-injection

这是一个基本的类构造,在使用DI之前(我知道,它有点不正确的结构,请尽量专注于问题)

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

class User
{
    public static function getWeight()
    {
        $mobile = new Mobile();
        return $mobile->getWeight();
    }
}
Run Code Online (Sandbox Code Playgroud)

更新后,使用DI:

class User
{
    public $mobile;

    public function getWeight()
    {
        return $this->mobile->getWeight();
    }
}
Run Code Online (Sandbox Code Playgroud)

如果我们检查,使用getWeight()没有要求有一个实例,User因为它是静态的 - 创建它的实例毫无意义.但现在,getWeight()不能是静态的,所以无论如何都需要一个实例 - 仅仅因为依赖注入!当然,我知道这个例子有点跛 - 我只是想指出依赖注入杀死静态方法的逻辑,但有时候需要静态方法,因为它有一个类的实例没有意义,只想到JAVA Math.max()方法.如何解决?

Sve*_*ven 6

是的,依赖注入使静态方法变得不必要,但是你没有看到它的原因是因为你的例子选择不当.

静态方法仍然有用.但是它们不应该在应用程序的构造根点之外使用.

这个建筑的根源是什么?每个应用程序都在静态的全球化世界中开始.$ _SERVER,$ _GET和$ _POST中有请求信息,有一个请求的URL,可以在中央文件中处理,甚至指向相应的脚本文件.

然后我们实现模型,业务逻辑,用于表单验证,模板化等的实用程序对象 - 如果做得好,这些都没有静态方法,但都需要实例化.

这没有问题,因为它们都被实例化 - 可能借助于依赖注入容器.因此,构造根是好对象的实例世界满足每个请求的静态全局世界的地方.确定会议发生的确切层是一种很好的做法,即除此之外不应该有静态调用.

本质上:如果您能够使用DI容器,您将在静态全局世界中对其进行配置,然后,可能在控制器中,请求它为对象.这将创建所有需要的子对象,根据需要将它们全部注入到彼此中,并仅返回您请求的主对象的一个​​实例.而且您不必担心如何注入所有这些其他对象 - 它们已经存在.

最后一句话:为什么静态通话不好?因为它们将此调用静态链接到所使用的类.您不能简单地通过传递实现相同接口的不同对象或从同一父对象继承来将此调用替换为另一个类.你必须改变代码.

你的Java的例子Math.max()是另一种情况.在PHP中,这甚至不是一个对象,而只是一个全局函数.它的工作原理是因为此函数不适用于任何对象实例 - 输入数据明确定义函数的输出.

但是,不要错误地定义您创建的每个方法,这些方法仅适用于输入参数并将输出作为静态返回.如果你有一个物体,那就享受吧.:)

  • 你不这样做.关键是:如果你进行依赖注入,你就不必使用静态方法(你仍然可以,但你很快就会遇到这种痛苦).根本没有必要,因为DI为您提供了所需的所有对象.您将对象创建与对象使用分开.在某种程度上,静态方法调用都是.您隐式创建并访问"god"类"对象",即托管静态方法的单个实例. (4认同)