2012-05-08 44 views
1

爲了解釋我的問題,讓我向您展示C#示例代碼。對Demeter原理的規律感到困惑

interface IConstructorInfoSelector 
{ 
    //ConstructorInfo is System.Reflection.ConstructorInfo class. 
    ConstructorInfo SelectConstructorInfo(Type declaringType); 
} 

class TestClass 
{ 
    private readonly ConstructorInfo _constructorInfo; 

    public TestClass(IConstructorInfoSelector constructorInfoSelector, Type type) 
    { 
     //Let the line to (A) 
     _constructorInfo = constructorInfoSelector.SelectConstructorInfo(type); 
    } 

    public TestClass(ConstructorInfo constructorInfo) 
    { 
     _constructorInfo = constructorInfo; 
    } 

    public Type GetTypeForConstructor() 
    { 
     //Let the line to (B) 
     return _constructorInfo.DeclaringType; 
    } 
} 

在例如,如果我構建的TestClass與構造函數(IConstructorInfoSelector,類型)並調用GetTypeForConstructor,其將通過線(A)和(B)違反毀滅之王(的得墨忒耳原理法) 。

但是,如果我執行下面的代碼,代碼是否違反LoD?我認爲,一方面,它沒有違反,因爲行(C)處的testClass對象在方法中被初始化,並且GetTypeForConstructor方法被調用,另一方面,它似乎違反了上述情況下的原則。總而言之,如果一個返回對象被用來創建另一個對象,這個執行將被認爲是違反了LoD?

class LoDQuestionForTestClass 
{ 
    public void DeosThisVoliateTheLoD() 
    { 
     IConstructorInfoSelector concreteSelector = ...; 
     Type testType = ...; 
     var selectConstructorInfo = concreteSelector.SelectConstructorInfo(testType); 
     //Let the line to (C) 
     var testClass = new TestClass(selectConstructorInfo); 
     var result = testClass.GetTypeForConstructor(); 
    } 
} 

回答

2

如果一個對象依賴於由第三個對象提供的另一個對象的行爲,那麼違反了LoD。其中的民意verion是「不要相信朋友的朋友」

在你的第二個例子中,你有另一個對象取決於第三方提供的對象,所以是的,這違反了「不相信朋友的朋友「,但,如果selectConstructorInfo只用於它的價值。

值得注意的是LoD是爲特定的項目(德米特)創建的,並且它以最嚴格的形式可能不適用於任何其他項目。

+0

感謝您的回答。我能再提一些問題嗎? 1)你可以給我更多關於「除非selectConstructorInfois只用過...」的信息。這意味着該方法僅返回值(或對象)作爲指定的返回類型,而沒有邏輯或操作。 –

+0

對不起,它有點長。 2)據我所知,保持LoD原則意味着一個方法應該只返回簡單的值(int,string等)或數據結構的值如DTO(數據傳輸對象),因爲任何返回值的方法不應該在鏈接狀態下使用。 –

+0

@jwjung任何對象都有行爲,但也是一個值。在你的情況下,如果你比較selectedConstructorInfo與另一個對象,你正在使用它的價值。如果使用Invoke方法構造一個新對象,則您現在依賴朋友朋友的行爲,這違反了LoD –