2013-10-23 26 views
0

假設下課時德米特檢驗的IntelliJ Idea法則。假陽性還是不假?

interface Thing { 
    void doSomething(); 
} 

public class Test { 
    public void doWork() { 
    //Do smart things here 
    ... 
    doSomethingToThing(index); 
    // calls to doSomethingToThing might happen in various places across the class. 
    } 

    private Thing getThing(int index) { 
    //find the correct thing 
    ... 
    return new ThingImpl(); 
    } 

    private void doSomethingToThing(int index) { 
    getThing(index).doSomething(); 
    }  
} 

的Intelli-J是告訴我,我犯法德米特因爲DoSomethingToThing使用函數的結果,據說你只能調用字段,參數或方法對象本身。

難道我真的有做這樣的事情:

public class Test { 
    //Previous methods 
    ... 

    private void doSomething(Thing thing) { 
    thing.doSomething(); 
    } 

    private void doSomethingToThing(int index) { 
    doSomething(getThing(index)); 
    } 
} 

我覺得這很麻煩。我認爲德米特的法則是這樣,一個班級不知道另一個班級的內部,但getThing()是同一班!

這是否真的違反了德米特法?這真的是改進設計嗎?

謝謝。

回答

0

從技術上講,這是打破德米特法則。雖然我會爭辯說LoD-F應該考慮私人功能,因爲據說他們不能從外面訪問。同時,如果'事情'歸Test所有,這並不是真的打破了Demeter的法律。但是在Java中,獲取事物的唯一方法可能是通過一個getter,它將這轉回到技術性(getter和action方法之間沒有明確的區分)。

我會說,這樣做:

public class Test { 
    private Thing getThing(int index) { 
    //find the thing 
    return thing; 
    } 

    private void DoSomethingToThing(Thing thing) { 
    thing.doSomething(); 
    } 

    private void DoSomethingToThing(int index) { 
    DoSomethingToThing(getThing(index)); 
    } 
} 

或者,可能會更好,直接讓主叫方使用的東西。如果測試的功能是產生或揭示事物,而不是作爲操縱事物的媒介,那麼這是可能的。

+0

你的意思是什麼東西暴露方法,做的東西呢?因爲Thing公開了'doSomething()'。除此之外它似乎你建議我必須添加額外的方法。對? – superjugy

+0

對不起,修正了。我建議直接操作,和/或重載,所以它看起來更整齊。 –

+0

那麼這裏的東西是Thing是一個真正的接口,getThing實例化真實的類。但是Thing只能在私人測試中使用。我會更新試圖反映這一點的問題。 – superjugy

0

IntelliJ未正確檢測對象實例。

維基百科(哪些IDEA鏈接)描述了您可以調用在當前上下文中創建的對象。

這就是我做的,但是我還是對getMajor()警告:

Version version = Loader.readVersion(inputStream); // Instantiates a new Version 

if (version.getMajor() != 2) 
    throw new IOException("Only major version 2 is supported"); 

IDEA的檢驗提供了一個選項忽略到「庫」方法的調用。在我的情況下,Loader.readVersion()庫方法,但它位於當前項目中(該項目必須是自支持的)。 IDEA認爲這不是一個庫方法。由於這種檢查的機制不夠完整/天真(像IDEA的檢查btw 很多),唯一的解決辦法是禁用它,並試圖避免這些情況手動。

+0

那麼,在我的例子中,實例正在被創建並在同一個類中使用。在你的情況下,你正在類之外創建實例。但我同意。同樣,如果你想使用任何依賴注入器,這將始終發生,因爲注入器會爲你提供所需對象的創建實例。我最終禁用了這項檢查。 – superjugy