'Array#dig' 或 'Hash#dig' 方法是否违反 Demeter 法则?

Do the 'Array#dig' or 'Hash#dig' methods violate the Law of Demeter?

dig方法:

Extracts the nested value specified by the sequence of idx objects by calling dig at each step, returning nil if any intermediate step is nil.

这意味着:

[1, {foo: :bar}].dig(1, :foo)

returns :bar 通过依次对 Array 对象和 Hash 对象执行查找。

dig 的第一次调用是在 Array 对象上进行的,但对 dig 的下一次调用是对从 [=14] 返回的 Hash 对象进行的=].

dig的使用是否违反了Law of Demeter

dig 几乎只是数组的语法糖和您在引入该方法之前执行的散列访问,因此它不会比您已经违反得墨忒尔法则更多或更少。考虑你的例子:

[1, {foo: :bar}].dig(1, :foo)
[1, {foo: :bar}][1][:foo]

您拥有相同的数据结构,获得相同的值,但令人高兴的是,现在您也不必在每一步都检查 nil

Demeter 法则是一种设计启发法。如果您发现自己通过三个对象来完成某件事,则执行此操作的代码必须了解所有这三个对象的相关信息。这表明您可能想要重构以减少模块所具有的依赖项数量,但是您用来实现到达的方法,无论是 [] 还是 dig,并不完全相关。

是的,可以说是。但只是通常的做法,hash[:foo][:bar][:baz] 或(更安全地)hash[:foo] && hash[:foo][:bar] && hash[:foo][:bar][:baz]dig 是这些的快捷方式。

我认为你是在正确的轨道上使用嵌套散列传递复杂数据类似于违反得墨忒耳法则,无论是否使用挖掘,它都在做类似得墨忒耳法则的事情是反对。从某种意义上说,您的代码需要了解散列的结构,而不仅仅是调用带有明确 API 的方法。然后可以说 dig 正在采取一种经常发生的违反 LoD 的行为 - 并使其更容易做到,纯粹主义者可能会说这是一个坏主意。

但在实际编程中,至少在 ruby 中,Demeter 法则更像是一个普遍的好主意,而不是盲目遵循的实际法则。

也有人可能会争辩说,在某些方面 dig 避免了没有它时发生的 LoD 违规。 技术上 当使用 dig 你不再违反 LoD,因为你现在只是调用 one 方法(第一个 dig call) 在您直接引用的对象上。我不认为技术性太重要,无论哪种方式,你实际上都在做同样的事情。