问题描述
这是一个通用的假想例子,用于这篇文章。考虑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.
另请参阅
这篇关于依赖地狱 - 如何将依赖关系传递给深层嵌套的对象?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!