PHP中何时需要依赖注入?

时间:2013-01-11 08:17:37

标签: php dependency-injection

依赖注入(DI)对于拥有多个团队成员的大型企业应用程序更重要吗?现在我是一个单一的开发人员试图破解一个小网站,看看它是否获得牵引力。但是,我不相信DI会为我正在编写的代码增加价值,尽管这个社区给予了大力支持。

我花了最后一周研究DI并在我的代码中实现,这并不困难。但我仍然没有看到解耦和单元测试的好处。相反,它似乎使代码更难理解,编写时间更长,并且可能存在性能问题。在我浪费时间实施DI之前,我对以下问题感兴趣。

1)解耦的好处? 我不知道DI如何使代码更少依赖。代码本质上需要相互依赖才能发挥作用。 DI只是将此依赖关系移动到您没有看到它的另一个区域。例如,假设我有一个调用另一个静态方法的方法。

class User {

// Static Dependency //
function process_registration() {
    if(Form::validate($_POST['email'])) {
        Message::send_message("Registration Complete");
    }
}

// Dependency Injection //
function __construct($form, $message) {
    $this->form = $form;
    $this->message = $message;
}
function process_registration() {
    if($this->form->validate($_POST['email'])) {
        $this-message->send_message("Registration Complete");
    }
}
}

DI不会改变process_registrationFormMessage类的依赖性。即使将它们作为属性注入“用户”类,也不会process_registration 依赖在其类属性上工作吗?另外,如果我有一个容器将属性注入'User'类,那么方法也不会依赖于Container来实例化它的类吗?假设我将来将“process_registration”重构为另一个类,或者将其重用于另一个项目。无论是否使用DI,该方法都将停止工作,因为可能不存在相同的类属性和注入容器。

2)代码可读性? 从上面的示例中可以看出,process_registration方法所需的代码现在已经翻了一番。如果考虑我每次实例化一个新类时需要修改的Container类,或者每次修改一个类方法时,都要加倍。除此之外,代码现在不那么直观了。 $database$form$message等属性如何与User相关联?代码也不那么优雅。以前,我的静态方法是!Form::validate(),两个字。现在,它是$this->form->validate(),长30%。这影响了我注入课堂的所有方法。所以现在,当我查看代码页时,$this->$this->$this->重复了一百次,而不是立即描述的静态方法。而不是$user=new User($user_id);现在是ioc::get('user')->newUser($user_id);。我的观点是DI鼓励使用非PHP标准的惯用代码。

3)更好的表现? DI鼓励实例化可能永远不会被使用的对象(例如,当验证失败或抛出错误时),而不是在准备使用时调用Just In Time方法。如果这些对象具有大型库并且加载繁重(例如PHPExcel),则这可能是性能问题。这将是什么工作?

4)单元测试? 中小型项目是否需要进行代码测试?现在PHP在我的代码中出现错误时通知我。通过检查error_log,它们通常很容易查明和修复。如果我将来需要扩展我的项目,这会成为一个问题吗?如果没有,DI何时需要进行测试?

由于上述原因,我发现没有必要在我的项目中实施DI。但是,我感兴趣的是何时何地需要实施,所以我可以适当地这样做。请提供您自己的详细示例和支持与推理。我对其他文章的链接不感兴趣,因为它们可能很不清楚。提前谢谢!

1 个答案:

答案 0 :(得分:0)

1)想象一下,您想要更改Form类名。如果您使用了DI,那么在容器中注册Form类时,您只需要在一个地方进行更改。

使用DI进行单元测试更容易,因为您已经解耦了组件。您可以单独测试User,Message和Form类。在您的示例中,如果没有Message和Form类,则无法测试User类。

2)可读性与功能/可变长度无关。 DI提高了可读性,因为通过查看构造函数,您可以清楚地看到如何在某些类中使用WHICH依赖项。

3)我不知道不允许共享对象的单个DIC - 仅实例化一次并且根据请求(延迟加载)。

4)见1.