依赖地狱 - 如何将依赖关系传递给深层嵌套对象?

ste*_*lin 25 php dependencies unit-testing dependency-injection

这是一篇由这篇文章组成的通用虚构示例.考虑6个班级

TableFactory, TableData, TableCRUD, TableSchema, DBConnect, Logger. 
Run Code Online (Sandbox Code Playgroud)

TableFactory是外部类,假设它拥有TableDataDB表的对象.

在这里TableFactory,没有呼叫TableSchemaDBConnectlogger.我的目标是在外部范围内不需要的内部对象的示例.

TableData是一个内部提取和操作数据,所以它需要TableCrud,DBConnectLogger.

TableCrud 包含TableSchema和需要DBConnect,和Logger.

DbConnectitseld,为了让事情变得有趣,需要一个Logger.我的例子现在是3个范围深.

我的问题非常简单,如果你有一个对象3(或更多)范围,外部范围内的对象没有调用,那么如何在不破坏接口隔离原则的情况下将这些对象从外部范围发送到内部范围 - > TableFactory shouldn不得不处理内部对象所需的DBConnect或Logger.

如果一个人尊重基本的OOP原则并且目标是易于测试 - >你将需要注入5个对象的外部对象,然后使用getter方法来传递链上需要的对象.而内部范围的对象反过来又要求注入其内部3范围深度对象的依赖关系,并为这些对象注入getter.这使得外部作用域对象需要许多依赖项,而getter只是为了传递它们.

是否有替代这种对象传递方法,我一路上错过了什么?请分享!任何链接/评论赞赏.

Gor*_*don 48

这是一种常见的误解,即依赖关系需要通过对象图传递.总结MiškoHevery在清洁代码中给出的例子:不要寻找东西,需要门的房子,不需要知道门锁:

class HouseBuilder
{
    public function buildHouse()
    {
        $lock  = new Lock;
        $door  = new Door($lock);
        $house = new House($door);

        return $house;
    }
}
Run Code Online (Sandbox Code Playgroud)

正如你所看到的,House完全忘记了其中的门需要锁定的事实.HouseBuilder负责创建所有必需的依赖项,并在需要时将它们堆叠在一起.从里到外.

因此,在您的场景中,您必须确定哪些对象应该依赖于哪些依赖项(参见Demeter法则).然后,您的构建器必须创建所有协作者,并确保将依赖项注入适当的对象.

另请参阅如何考虑有关单元测试的"新"操作员

  • +1爱这个放的方式,干净整洁! (6认同)