【问题标题】:Query regarding dependency Injection in PHP查询PHP中的依赖注入
【发布时间】:2011-12-09 01:11:59
【问题描述】:

我一直在阅读依赖注入,我想我非常了解这些概念,包括构造函数注入和设置器注入。

但是,我不确定在以下情况下我会做什么:

假设我有一个包含许多方法的类,但只有一个这些方法需要某个其他对象。如何将此对象提供给该方法?我不应该像这样直接将对象作为参数传递给方法吗:

class aClass
{
    function aMethod(anotherClass $anotherClass)
    {
        anotherClass->hello();
    }

    function otherMethods()
    {
    }
    .....
}

另一种选择是将它提供给整个班级,这似乎没有必要。像这样:

class aClass
{
    protected $_anotherClass;

    function aMethod()
    {
        anotherClass->hello();
    }

    function otherMethods()
    {
    }
    .....

    function setAnotherClass(anotherClass $anotherClass)
    {
            $this->_anotherClass;
    }
}

什么时候应该将对象传递给方法,什么时候应该通过构造函数/设置器使用依赖注入? 对于何时使用这两个选项之一,是否有经验法则或最佳实践?

提前感谢您的帮助。

【问题讨论】:

  • 如果你的例子更具体,回答你的问题会更容易。 anotherClass 是什么,aMethod 用它做什么?
  • 好的,一个场景:我的电子商务网站中有一个 Basket 类。此 Basket 类中的方法之一称为 listProducts()。这是唯一需要访问产品数据库表的方法。这有它自己的数据映射器类,称为 productsMapper。第二种情况:我有一个带有 save() 方法的数据映射器类。此方法需要行的模型。向整个班级提供这个模型绝对没有意义。
  • 好的,我觉得这很直观,所以这里有具体的答案。第一种情况:注入——篮子可能会发出一些数据库请求。第二种场景:参数,你只需要存储一次数据,可能想存储其他模型使用相同的对象的功能。
  • @middus 太好了,这真的很有帮助,也是我的想法。是的,这很直观,但我确实喜欢遵循规则,可能是由于轻度强迫症! :)

标签: php oop dependency-injection loose-coupling


【解决方案1】:

你提到了一个经验法则,所以这里是:

问自己一个问题: 有人可以合法地在同一个对象上调用此方法两次,在两次调用中为参数提供不同的值吗?

如果是,则将其保留为参数。如果不是,那么正如您所描述的那样,它是一个很好的注射候选者。

This 是第一种方法的一个很好的例子,其中删除参数并在类中注入依赖项将是一个非常糟糕的主意。 C# 而不是 PHP,但你明白了。

【讨论】:

  • 啊,这确实很有意义,谢谢。尤其是使用数据映射器。将其保留为参数是否会降低我进行单元测试的难易程度?顺便说一句,我实际上还没有尝试过对任何东西进行单元测试!
  • @Azriel:当然不是。唯一会降低您的单元测试能力的是硬编码类型。
  • 我喜欢你的例子,简单明了。通过硬编码类型,我假设您的意思是 $anotherClass = new anotherClass() 在 aMethod() 方法中?
【解决方案2】:

一个类的内部工作与该类本身无关。如果只有一个函数需要依赖,那就这样吧。

另外,您可能想知道为什么只有一个函数具有依赖关系,您的班级可能会做两件不同的事情吗?

您不想在构造函数中注入依赖项的唯一原因是当制作该资源的成本非常高时(在磁盘上准备一个大文件,连接到远程主机等),但即使在这种情况下,你可以传入一个“代理”或“延迟”对象作为“承诺”,如果你需要它,你可以得到它。

【讨论】:

  • 但也有某些场景,例如,将数据库行的模型插入数据库的数据映射器。即使在 Zend QuickStart 指南中,我也看到了: public function save(Application_Model_Guestbook $guestbook) { } Is this not valid?
  • @Azriel 当然是,因为它是一个参数。如果你想保存一些东西,你需要知道要保存什么。
  • @middus 这正是我要提出的观点!我只是认为它与此答案中给出的内容相冲突。
猜你喜欢
  • 2010-11-27
  • 1970-01-01
  • 1970-01-01
  • 2023-03-28
  • 1970-01-01
  • 2017-02-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多