'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) 在您直接引用的对象上。我不认为技术性太重要,无论哪种方式,你实际上都在做同样的事情。
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) 在您直接引用的对象上。我不认为技术性太重要,无论哪种方式,你实际上都在做同样的事情。