oop - 得墨忒耳法则和 HashMap

我有几个问题。 首先,下面的代码是否违反了 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/

相关文章:

php - php中var-export函数的反义词是什么?

r - ggplot 中的条形图,每组条数不同

wcf - 检查权限的最佳位置在哪里?

wpf - 语音识别 - 未处理的异常 - 未找到 SAPI,即使已安装

cuda - 在 Cmake 项目中指定 openmp CUDA 标志

google-chrome - 使用 TFS/NUnit 通过构建过程执行时,使用 Google C

rest - 强制 web api 消费者接受响应中的新字段

php - 从 php 在计算机上运行脚本

ruby-on-rails - 如何从 Rails 中的模型继承,其中一种类型在不交织的情况下扩展另

haskell - GHCi - 第二次运行时跳过断点