2012-01-27 38 views
2

我有几个问题。 首先下面的代码违反了Demeter的规律吗?demeter的法则和hashmap

Map map = new HashMap<String, String>(); 
map.put("foo","bar"); 
map.put("fooo","baaar"); 
map.keySet().iterator() 

IMO以上代码违反了迪米特的法律,因为地图类型地图和keySet()返回集合对象。两者都不同。我正在考虑第二个属性只保存“键”,但这是正确的解决方案吗?

回答

1

是的,从技术上讲,这是在方法描述方面违反了德米特法。但是,修复它的方法是在这里将添加一个类似于“keysIterator”的操作到Map类,这可能是一个合理的操作,除了这里地图不是您的代码

迪米特法则的目的是降低你的应用程序的组件之间的耦合。改变你如何使用标准库对象不会影响到这一点。您提出的解决方案浪费资源,并没有特别的好处。

从另一个角度来看,Map的keySet实际上只是Map的一个方面。您应该将它看作不是第三个对象(LoD实质上是说在任何交互中不应该有两个以上的对象),作为对Map提供的操作进行分类的一种方式。


想像一个不同的场景:假设你有一个应用程序类公司,比如,在一个在线商店类别。这将是一个有意义的毁灭之王违反有

category.itemsSet().iterator() 

,这是东西,你可能要重构。为什么?因为它约束了Category类来实现一个Set,即使实际需要的唯一操作是迭代(或者,通常比Set接口具有更少的操作),而不是仅具有必需工作的实现,并且可以是修改或重新实现更容易。另一方面,如果您想对某个类别执行的操作覆盖所有Set操作,那么提供Category.itemsSet()方面是愚蠢的。


注:“小面”在此是指一个对象,它是在1:1的关系到另一个对象,并且基本上的“同样的事情”的不同视图,特别是更窄的图。这不是一个完全标准的术语。

+0

好说。你也不应该把“法律”看作是一种法律,而应该把它看作是一种建议或指导方针,当它有意义时可能被打破(正如凯文在这里所阐明的那样)。 – Dan 2012-01-27 23:26:11