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

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

问题描述

这是为这篇文章制作的通用假想示例.考虑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 中,没有对 TableSchemaDBConnectlogger 的调用.我的目标是在外部范围内不需要内部对象的示例.

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 是内部对数据的获取和操作,因此需要TableCrudDBConnectLogger.

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

TableCrud 包含 TableSchema 并且需要 DBConnectLogger.

TableCrud contains TableSchema and needs DBConnect, and Logger.

DbConnect 本身,为了让事情变得有趣,需要一个记录器.我的示例现在有 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.这使得外部作用域对象需要许多依赖项,而 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ško Hevery 在清洁代码:不要寻找事物中给出的例子,一个需要门的房子,不需要知道门锁:

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.

因此,在您的场景中,您必须确定哪些对象应该对哪些依赖项进行操作(参见 得墨忒耳法则).然后,您的 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天全站免登陆