嗯,对于该法则的简短定义过于简单了。实际上,“法则”(实际上是有关良好API设计建议)基本上是这样说的:只访问您自己创建的对象或作为参数传递给您的对象。不要通过其他对象间接访问对象。流畅接口的方法通常返回对象本身,因此,如果再次使用对象,则不违反该法律。其他方法为您创建对象,因此也没有任何违规行为。
另外,请注意,“法则”仅是“传统”API的最佳实践建议。 流畅接口是API设计的完全不同的方法,不能使用Demeter法则进行评估。
不一定。"只使用一个点"是对迪米特法则的不准确概括。
迪米特法则不鼓励在每个点表示不同对象的结果时使用多个点,例如:
然而,在我看来,如果每个点的返回对象仍为原始调用者的相同类型,则不会违反迪米特法则:
var List<SomeObj> list = new List<SomeObj>();
//initialize data here
return list.FindAll( i => i == someValue ).Sort( i1, i2 => i2 > i1).ToArray();
在上面的示例中,FindAll()和Sort()都返回与原始列表相同类型的对象。迪米特法则并没有被违反:列表只与其直接关联的对象交互。Demeter法则的精神是,针对一个对象引用或类,应该避免访问超过一个子属性或方法的类的属性,因为这将紧密耦合两个类,这可能是不想要的并且会导致可维护性问题。
流畅接口是该法则的可接受例外,因为它们旨在至少有些紧密耦合,因为所有属性和方法都是一种迷你语言的术语,这些术语组合在一起形成功能句子。
是的,虽然你需要对情况采取一些实用主义。我总是将Demeter法则作为指导方针而不是规则。
当然,你可能会想避免以下情况:
CurrentCustomer.Orders[0].Manufacturer.Address.Email(text);
CurrentCustomer.Orders[0].EmailManufacturer(text);
1)它完全不违反它。
该代码等同于
var a = new ZRLabs.Yael.Pipeline("cat.jpg");
a = a.Rotate(90);
a = a.Watermark("Monkey");
a = a.RoundCorners(100, Color.Bisque);
a = a.Save("test.png");
2) 正如Phil Haack所说:迪米特法则不是一个点计数的练习
你的例子没有问题。毕竟,你一直在旋转、加水印等操作同一张图片。我相信你一直在与 Pipeline 对象交互,只要你的代码仅依赖于 Pipeline 类,就不会违反 LoD 原则。
实际上,一个对象不应该暴露其内部(数据),而是应该暴露用于操作内部的函数。
考虑到这一点,流畅的API要求对象使用其数据来处理某些内容,而不是请求数据本身。
这并不违反任何迪米特法则。