依赖地狱 – 如何将依赖关系传递给深度嵌套的对象?

这里是一个通用的想象的例子,弥补了这个职位。 考虑6个class级

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

TableFactory是外部类,假设它拥有一个DB表的TableData对象。

在这个TableFactory ,不存在对TableSchemaDBConnectlogger调用。 我的目标是在外部范围内不需要的内部对象的例子。

TableData是内部读取和操作的数据,所以它需要TableCrudDBConnectLogger

TableCrud包含TableSchema并需要DBConnectLogger

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

我的问题是非常简单的,如果你有一个对象3(或更多)范围内的外部范围的对象没有调用,如何将这些对象从外部发送到内部范围而不会破坏接口分离原则 – > TableFactory shouldn不必处理内部对象所需的DBConnect或Logger。

如果一个人遵守基本的面向对象的原则,并且为了易于testing而devise – >你将有外部对象需要注入这5个对象,然后有一个getter方法来把这些对象所需要的东西传递到链上。 而内部作用域对象又需要注入它们内部的3范围深度对象的依赖关系,也需要注入这些对象的getters。 这使得外部作用域对象需要很多的依赖,而getter只是传递这些依赖关系。

除了这种传递物体的方法,还有其他的方法吗? 请分享! 任何链接/评论赞赏。

依赖关系需要通过对象图传递是一个常见的误解。 总结MiškoHevery在Clean Code中给出的例子:不要找东西 ,需要门的房子,不需要知道门锁:

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

正如你所看到的,众议院完全没有意识到这个事实,门在里面需要锁。 HouseBuilder负责创build所有必需的依赖关系,并在需要时将它们堆叠在一起。 从里到外。

因此,在你的情况下,你必须确定哪些对象应该在哪些依赖关系上进行操作(参见Demeter法则 )。 你的Builder然后必须创build所有的协作者,并确保依赖被注入到适当的对象中。

另请参阅如何考虑关于unit testing的“新”操作符

如果你在同一个问题上磕磕绊绊,请查看赫维的文章,点击牛眼

http://misko.hevery.com/2008/10/21/dependency-injection-myth-reference-passing/

如果这篇文章将来在这里消失的话,那就是摘录

“每个对象只是知道它直接与之交互的对象,没有任何对象传递只是为了让它们进入需要的地方。

所以,我们需要做的不是创build一个深层嵌套的对象图,将依赖关系从上到下传递,横向并pipe理别处的依赖关系。