对德米特原理的规律感到困惑

时间:2012-05-08 06:29:00

标签: c# design-principles law-of-demeter

为了解释我的问题,让我用C#向您展示示例代码。

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;
    }
}

在该示例中,如果我使用ctor(IConstructorInfoSelector,Type)构造TestClass并调用GetTypeForConstructor,它将通过(A)和(B)行违反LoD(Demeter原则)。

但是,如果我执行以下代码,代码是否违反了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();
    }
}

1 个答案:

答案 0 :(得分:2)

如果一个对象依赖于第三个对象提供的另一个对象的行为,则会违反LoD。其中的民粹主义是“不要相信朋友的朋友”

在你的第二个例子中,你有另一个对象,取决于第三方提供的对象,所以是的,这确实违反了“不信任朋友的朋友”除了,如果selectConstructorInfo只是用它的价值。

值得注意的是,LoD是为特定的项目(Demeter)创建的,并且它的最严格形式可能不适用于任何其他项目。