依赖地狱 – 如何将依赖关系传递给深度嵌套的对象?
这里是一个通用的想象的例子,弥补了这个职位。 考虑6个class级
TableFactory, TableData, TableCRUD, TableSchema, DBConnect, Logger.
TableFactory
是外部类,假设它拥有一个DB表的TableData
对象。
在这个TableFactory
,不存在对TableSchema
或DBConnect
或logger
调用。 我的目标是在外部范围内不需要的内部对象的例子。
TableData
是内部读取和操作的数据,所以它需要TableCrud
, DBConnect
和Logger
。
TableCrud
包含TableSchema
并需要DBConnect
和Logger
。
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理别处的依赖关系。