2012-01-27 20 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