我见过的LOD描述(例如,Wikipedia,C2 Wiki)谈论不调用方法。引用维基百科:
函数的Demeter定律要求对象O的方法M可以仅调用以下类型对象的方法:
- O本身
- M的参数
- 在M
中创建/实例化的任何对象 - O的直接组件对象
- 一个全局变量,可由O访问,范围为M
但是访问属性,变量或枚举呢?例如,鉴于此:
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";
}
是否存在任何/所有LOD违规行为? (暂时忽略直接变量访问,如果可以的话......)
void Violate(FirstClass first) {
SecondClass second = first.GetRelatedClass();
var x = second.Property;
var y = second._variable;
var z = FirstClass.InnerEnum.Violated;
}
我不会做前两个(无论是否是'官方'违规行为),但对enum不太确定。
答案 0 :(得分:6)
我无法回答关于枚举问题 - 我似乎记得标准建议不是在类中定义枚举。
对于属性,您可以将属性视为方法的快捷方式(getProperty()
和setProperty(value)
)。在这种情况下,您的答案是财产访问是违规行为。
对于字段(变量),再一次,通常的做法不是暴露它们而是使用属性,实际暴露字段是违反封装的。
最终,Demeter法的目的是限制类之间的实现知识。对我来说,这意味着你的所有例子都是违规行为。
答案 1 :(得分:1)
... FWIW
违规#1(x)看起来像一个粗略的服务位置模式,所以我怀疑该示例不是违规。
违规#2(y)看起来像是一种类设计气味,但通常没有证明任何超出#1违规行为的内容。
我不认为公共枚举(z),但是它们是作用域的,在这里会反对LOD。
你有一个更好的现实世界的例子来证明你的担忧吗?没有适当的上下文,简单的代码示例可能没问题,或者它们可能违反设计原则。