我有几个问题。 首先,下面的代码是否违反了 Demeter 法则?
Map map = new HashMap<String, String>();
map.put("foo","bar");
map.put("fooo","baaar");
map.keySet().iterator()
上面的 IMO 代码违反了 Demeter 法则,因为 map 类型是 Map 并且 keySet() 返回 Set 对象。两者不同。我正在考虑第二个属性(property)只持有“ key ”,但这是正确的解决方案吗?
最佳答案
是的,从技术上讲,当用方法来描述时,这违反了 Demeter 法则。然而,解决这个问题的方法是向 Map 类添加一个像“keysIterator”这样的操作,这可能是一个合理的操作,除了这里 Map 不是你的代码。
Demeter 法则的目的是减少应用程序组件之间的耦合。更改您使用标准库对象的方式不会影响这一点。您提出的解决方案浪费资源并且没有特别的好处。
从另一个角度来看,Map 的keySet 实际上只是Map 的一个facet。您不应将其视为第三个对象(LoD 本质上说您在任何交互中不应该有两个以上的对象),而是将 Map 提供的操作分类的一种方式。
想象一个不同的场景:假设您有一个应用程序类,例如在线商店中的类别。这将是一个有意义的 LoD 违规
category.itemsSet().iterator()
这是您可能想要重构的东西。为什么?因为它限制了 Category 类来实现一个 Set,即使实际需要的唯一操作是迭代(或者通常比 Set 接口(interface)具有的操作更少),而不是有一个只做必要工作并且可以是更容易修改或重新实现。
另一方面,如果您想对 Category 执行的操作涵盖所有 Set 操作,那么不提供 Category.itemsSet()
facet 就是愚蠢的做法。
注意:这里的“Facet”指的是一个对象与另一个对象是1:1的关系,本质上是“同一事物”的不同视角,尤其是更窄的视角。这不是一个完全标准的术语。
https://stackoverflow.com/questions/9039787/