迪米特定律只适用于方法吗?
我见过的 LOD 描述(例如,Wikipedia、C2 Wiki) 谈论不调用方法。引用维基百科:
函数的得墨忒耳定律要求对象 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;
}
我不会做前两个(无论是否“官方”违规),但对枚举不太确定。
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.Property;
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.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
我无法回答枚举问题——我似乎记得标准建议是不要在类中定义枚举。
对于属性,您确实可以将属性视为方法的快捷方式(
getProperty()
和setProperty(value)
)。在这种情况下,您的答案是财产访问属于违规行为。对于字段(变量),通常的做法不是公开它们而是使用属性,真正公开字段是违反封装性的。
但最终,德米特法则的目的是限制类之间的实现知识。对我来说,这意味着你所有的例子都是违规的。
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()
andsetProperty(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...
违规 #1 (x) 看起来像是一个粗略的服务位置模式,所以我怀疑该示例不是违规。
违规 #2 (y) 看起来像是类设计的味道,但通常不会表现出高于违规 #1 所展示的任何内容。
我认为公共枚举 (z),无论其范围如何,都不会在此处对 LOD 产生影响。
您有更好的现实世界例子来证明您的担忧吗?如果没有适当的上下文,简单的代码示例可能没问题,否则可能会违反设计原则。
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.