这是一个基本的类构造,在使用DI之前(我知道,它有点不正确的结构,请尽量专注于问题)
class Mobile
{
public function getWeight()
{
return 4;
}
}
class User
{
public static function getWeight()
{
$mobile = new Mobile();
return $mobile->getWeight();
}
}
更新后,使用DI:
class User
{
public $mobile;
public function getWeight()
{
return $this->mobile->getWeight();
}
}
如果我们检查,使用getWeight()
并没有要求拥有User
的实例,因为它是静态的 - 创建它的实例毫无意义。
但是现在,getWeight()
不能是静态的,所以无论如何都需要一个实例 - 只是因为依赖注入!当然,我知道这个例子有点跛 - 我只想指出依赖注入杀死静态方法的逻辑,但有时需要静态方法,因为它有一个类的实例没有意义,只想到JAVA {{ 1}}方法。
如何解决它?
答案 0 :(得分:6)
是的,依赖注入使得静态方法变得不必要,但你没有看到它的原因是因为你的例子选择不当。
静态方法仍有用处。但是它们不应该超出应用程序中的构造根点。
这个建筑根源是什么?每个应用程序都在静态的全球化世界中开始。在$ _SERVER,$ _GET和$ _POST中有请求信息,有一个请求的URL,可以在中央文件中处理,甚至指向相应的脚本文件。
然后我们实现模型,业务逻辑,用于表单验证,模板化等的实用程序对象 - 如果做得好,这些都没有静态方法,但都需要实例化。
这没有问题,因为它们都被实例化 - 可能借助于依赖注入容器。因此,构造根是好对象的实例世界满足每个请求的静态全局世界的地方。确定会议发生的确切层是一个很好的做法,即除此之外不应该有静态调用。
实质上:如果你能够使用DI容器,你将在静态全局世界中配置它,然后,可能在控制器中,要求它提供一个对象。这将创建所有需要的子对象,根据需要将它们全部注入到彼此中,并仅返回您请求的主对象的一个实例。而且您不必担心如何注入所有这些其他对象 - 它们已经存在。
最后一句话:为什么静态通话不好?因为它们将此调用静态链接到所使用的类。您不能简单地通过传递实现相同接口的不同对象或从同一父对象继承来将此调用替换为另一个类。你必须改变代码。
你的Java Math.max()
的例子是另一种情况。在PHP中,这甚至不是一个对象,而只是一个全局函数。它的工作原理是因为此函数不适用于任何对象实例 - 输入数据明确定义函数的输出。
但是,不要错误地定义您创建的每个方法,这些方法仅适用于输入参数并将输出作为静态返回。如果你有一个物体,那就享受吧。 :)