2011-11-24 49 views
1

假設你有類似於以下(可悲的是,我不能發佈原碼):此方法調用是否違反Demeter法則?

public void foo() { 
    MyObject obj = getMyObject(); 

    bar(obj); 
} 

public void bar(MyObject obj) { 
    Type type = new Type(obj.getOtherObject()); 
} 

foo電話bar,通過在obj。但不是使用obj,而是調用getter來檢索所需的信息。這是否違反了德米特法?

它會更好寫的是這樣的:根據對Law of Demeter維基

public void foo() { 
    MyObject obj = getMyObject(); 

    bar(obj.getOtherObject()); 
} 

public void bar(MyOtherObject otherObj) { 
    Type type = new Type(otherObj); 
} 

回答

2

事實上:

的基本概念是,一個給定的對象應該承擔儘可能少 爲可能關於其他任何結構或屬性...

您的bar假定給定的MyObject(具體類型如此強烈耦合,再次針對LoD)有一個名爲getOtherObject的方法,因此您提出的解決方案將假設分類並將代碼更接近於遵循LoD。你可以更進一步,而是提供類型bar想:

bar(new Type(obj.getOtherObject());

根據你的語言,你能不能傳遞一個接口/合同代替固態類型的?這會將強耦合變爲鬆散耦合。

當然,如果這是所有內部給定對象,那麼也許它沒有打破毀滅之王,因爲這是一個「密友」:

  • 每個單位應該有大約只有其他單位的知識有限:只有與當前單位「密切」相關的單位。
  • 每個單位只能跟朋友交談;不要與陌生人交談。
  • 只與您的直接朋友交談。

在OO我認爲你原來的代碼是基於這樣的說法打破毀滅之王:

...一個對象可以請求服務(調用方法)的對象 實例B的,但是對象A不能「到達」對象B來訪問另一個對象C以請求其服務。這樣做意味着對象A隱含地要求對對象B的內部結構有更多的瞭解。

對我來說,似乎你正在使用obj爲了打電話給getOtherObj。你提出的代碼是一個潛在的解決方案