依赖地狱 - 如何将依赖关系传递给深层嵌套的对象? [英] Dependency Hell — how does one pass dependencies to deeply nested objects?

查看:96
本文介绍了依赖地狱 - 如何将依赖关系传递给深层嵌套的对象?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这是一个通用的假想例子,用于这篇文章。考虑6个课程

Here is a generic imaginary example made up for this post. Consider 6 classes

TableFactory, TableData, TableCRUD, TableSchema, DBConnect, Logger. 

TableFactory 是外部类,它为数据库表保存一个 TableData 对象。

TableFactory is the outer class, let's say it holds a TableData object for a DB table.

在这个 TableFactory ,没有调用 TableSchema DBConnect logger 。我的目标是在外部范围内不需要的内部对象的例子。

In this TableFactory, there are no calls to TableSchema or DBConnect or logger. I am aiming for an example of inner objects not needed in outer scope.

TableData 是一个内部获取和操作在数据上,所以需要 TableCrud DBConnect Logger

TableData is an inner fetches and operates on the data, so it needs TableCrud, DBConnect and Logger.

TableCrud 包含 TableSchema ,需要 DBConnect Logger

DbConnect itseld,让事情变得有趣,需要一个记录器。我的例子现在是3个范围。

DbConnect itseld, to make things fun, needs a Logger. My example is now 3 scopes deep.

我的问题很简单,如果你有一个对象3(或更多)外部范围上的对象,如何将这些对象从外部范围发送到内部范围,而不会破坏界面分隔原则 - > TableFactory不应该处理内部对象所需的DBConnect或Logger。

如果尊重基本的OOP原则,并且旨在轻松实现可测性 - >您将需要注入5个对象的外部对象,然后使用getter方法,以便在链上进一步传递所需的对象。而内部范围对象反过来又需要注入它们内部3层深度物体的依赖关系,以及吸收剂。这使得需要许多依赖性的外部范围对象,并且getter只是为了传递这些对象。

If one respects basic OOP principles and aims for easy testability -> you would have outer objects needing injection of the 5 objects, and then have getter methods that woud pass the objects needed further up the chain. And inner scoped objects would in turn require injection of the dependencies of their inner 3-scope-deep objects, with getters for those too. This makes for outer scoped objects requiring many dependencies, and getters just to pass those on.

有没有替代这种对象传递方法,我错过了一些?请分享!任何链接/评论赞赏。

Is there an alternative to this object-passing methodology, something I missed along the way? Please share! Any links/comments appreciated.

推荐答案

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

It's a common misconception that dependencies need to be passed through the object graph. To summarize the example Miško Hevery gives in Clean Code: Don't look for things, a House that needs a Door, doesnt need to know about the Lock in the Door:

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

        return $house;
    }
}

如你所见,House完全忘记了事实上,其中的门需要锁。 HouseBuilder有责任创建所有必需的依赖项,并根据需要将它们堆叠在一起。从内而外。

As you can see, House is completely oblivious of the fact that the Door in it requires a lock. It's the responsibility of the HouseBuilder to create all the required dependencies and stack them together as they are needed. From the inside out.

因此,在您的方案中,您必须确定哪些对象应在哪些依赖项上进行操作(cf 德米特法则)。然后,您的Builder将必须创建所有协作者,并确保将相关性注入相应的对象。

Consequently, in your scenario you have to identify which objects should operate on which dependencies (cf Law of Demeter). Your Builder then has to create all collaborators and make sure the dependencies are injected into the appropriate objects.

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

这篇关于依赖地狱 - 如何将依赖关系传递给深层嵌套的对象?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆