2013-10-20 26 views
2

这里是一个基本的类结构,使用DI之前(我知道,它有点不正确的结构,请你只把注意力放在这个问题)PHP,依赖注入 - 杀死静态方法,但instatize是不必要

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 Math.max()方法。 如何解决它?

回答

6

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

静态方法仍然有用。但是它们不应该超出应用程序的构建根源。

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

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

这是没有问题的,因为它们都被实例化 - 可能借助于依赖注入容器。因此,构建根就是好物体的实例世界满足每个请求的静态全局世界的地方。确定会议发生的确切层次是一个很好的做法,即在那之后不应该有静态调用。本质上:如果你能够使用一个DI容器,你将在静态全局世界中配置它,然后,可能在控制器中,请求它为一个对象。这将创建所有需要的子对象,根据需要将它们全部注入到对方中,并且只返回您请求的主对象的一个​​实例。而且您不必担心如何注入所有这些其他对象 - 它们已经在那里。

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

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

但是不要犯错误的定义你创建的每个方法,只对输入参数有效,并将输出返回为静态。如果你有一个物体,享受它。:)

+0

多数民众赞成好,但我仍然没有看到为什么要做一个方法非静态只是因为依赖注入 –

+4

你不这样做。重点是:如果你进行依赖注入,你不必使用静态方法(你仍然可以,但很快就会遇到这种情况)。根本没有必要了,因为DI给你你需要的所有物体。您将对象创建与对象使用分开。从某种意义上来说,静态方法调用也是。你隐式创建并访问那个“上帝”类的“对象”,这个单一的实例托管静态方法。 – Sven

+1

@Sven - 听起来像是单身模式?例如,假设我们需要静态方法中的依赖项('MyClass :: new(params)' - 将项目保存到数据库),将数据库连接/链接传递给静态方法的最佳方式是什么,if它不能通过构造函数的参数实例化? – 1234567