The LOD description I've seen (for example, Wikipedia, C2 Wiki) talk about not calling methods. To quote Wikipedia:
The Law of Demeter for functions requires that a method M of an object O may only invoke the methods of the following kinds of objects:
- O itself - M's parameters - any objects created/instantiated within M - O's direct component objects - a global variable, accessible by O, in the scope of M
But what about accessing properties, variables or enums? For example, given this:
class FirstClass {
public SecondClass GetRelatedClass() {
return new SecondClass();
}
public enum InnerEnum {
Violated,
NotViolated
}
}
class SecondClass {
public int Property {get; set;}
public string _variable = "Danny Demeter";
}
Are any/all of these LOD violations? (Ignore the direct variable access for now, if you can..)
void Violate(FirstClass first) {
SecondClass second = first.GetRelatedClass();
var x = second.P开发者_开发知识库roperty;
var y = second._variable;
var z = FirstClass.InnerEnum.Violated;
}
I wouldn't do the first two (whether 'official' violations or not), not quite so sure about the enum though.
I can't answer on the enum question -- I seem to recall that the standard recommendation is not to define enums inside of a class.
For properties, you can really consider properties to be shortcuts to methods (getProperty()
and setProperty(value)
). In that case, your answer is that property accesses are violations.
For fields (variables), once again, common practice is not to expose them but rather to use properties, really exposing fields is a violation of encapsulation.
Ultimately though, the intent of the Law of Demeter is to limit the knowledge of implementation between classes. To me that means all of your examples are violations.
FWIW...
Violation #1 (x) looks like a rough service location pattern, so I would suspect that the example is not a violation.
Violation #2 (y) looks like a class design smell, but generally doesn't demonstrate anything above what violation #1 demonstrates.
I don't think that public enumerations (z), however they are scoped, would count against LOD here.
Do you have a better real world example to demonstrate your concerns? Without proper context, simple code examples could be ok, or they could violate design principles.
精彩评论