流畅的界面是否违反了德米特定律?

发布于 2024-07-05 19:03:11 字数 621 浏览 11 评论 0原文

关于德墨忒尔定律 说:

该定律可以简单地表述为“仅使用一个点”。

然而 简单流畅界面的示例可能如下所示:

static void Main(string[] args)
{
   new ZRLabs.Yael.Pipeline("cat.jpg")
        .Rotate(90)
        .Watermark("Monkey")
        .RoundCorners(100, Color.Bisque)
        .Save("test.png");
}

那么这可以组合在一起吗?

The wikipedia article about Law of Demeter says:

The law can be stated simply as "use only one dot".

However a simple example of a fluent interface may look like this:

static void Main(string[] args)
{
   new ZRLabs.Yael.Pipeline("cat.jpg")
        .Rotate(90)
        .Watermark("Monkey")
        .RoundCorners(100, Color.Bisque)
        .Save("test.png");
}

So does this goes together?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(7

ゞ记忆︶ㄣ 2024-07-12 19:03:11

不必要。 “只使用一个点”是对德米特法则的不准确概括。

当每个点代表不同对象的结果时,德米特法则不鼓励使用多个点,例如:

  • 第一个点是从 ObjectA 调用的方法,返回 ObjectB 类型的对象
  • 下一个点是仅在 ObjectB 中可用的方法,返回ObjectC 类型的对象
  • Next dot 是仅在 ObjectC 中可用的属性,
  • 并且无限。

,如果每个点的返回对象仍然与原始调用者的类型相同,则不会违反 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() 都返回与原始列表相同类型的对象。 德米特定律并没有被违反:该列表只与它的直接好友交谈。

话虽如此,并非所有流畅的接口都违反了得墨忒耳定律,只要它们返回与调用者相同的类型即可。

Not necessarily. "Only use one dot" is an inaccurate summary of the Law of Demeter.

The Law of Demeter discourages the use of multiple dots when each dot represents the result of a different object, e.g.:

  • First dot is a method called from ObjectA, returning an object of type ObjectB
  • Next dot is a method only available in ObjectB, returning an object of type ObjectC
  • Next dot is a property available only in ObjectC
  • ad infinitum

However, at least in my opinion, the Law of Demeter is not violated if the return object of each dot is still the same type as the original caller:

var List<SomeObj> list = new List<SomeObj>();
//initialize data here
return list.FindAll( i => i == someValue ).Sort( i1, i2 => i2 > i1).ToArray();

In the above example, both FindAll() and Sort() return the same type of object as the original list. The Law of Demeter is not violated: the list only talked to its immediate friends.

That being said not all fluent interfaces violate the Law of Demeter, just as long as they return the same type as their caller.

剩余の解释 2024-07-12 19:03:11

好吧,法律的简短定义使其变得过于简短。 真正的“法则”(实际上是关于良好 API 设计的建议)基本上是这样说的:只能访问您自己创建的对象,或者作为参数传递给您的对象。 不要通过其他对象间接访问对象。 流畅接口的方法通常返回对象本身,因此如果您再次使用该对象,它们不会违反法律。 其他方法为您创建对象,因此也不存在违规。

另请注意,“法则”只是针对“经典”API 的最佳实践建议。 流畅的接口是一种完全不同的 API 设计方法,不能用德米特定律来评估。

Well, the short definition of the law shortens it too much. The real "law" (in reality advice on good API design) basically says: Only access objects you created yourself, or were passed to you as an argument. Do not access objects indirectly through other objects. Methods of fluent interfaces often return the object itself, so they don't violate the law, if you use the object again. Other methods create objects for you, so there's no violation either.

Also note that the "law" is only a best practices advice for "classical" APIs. Fluent interfaces are a completely different approach to API design and can't be evaluated with the Law of Demeter.

一杯敬自由 2024-07-12 19:03:11

得墨忒耳定律的精神是,给定一个对象引用或类,您应该避免访问一个类的属性,该类的属性超过一个子属性或方法,因为这会将两个类紧密耦合,这可能是无意的,并可能导致可维护性问题。

流畅的接口是法律上可接受的例外,因为它们意味着至少在某种程度上紧密耦合,因为所有属性和方法都是迷你语言的术语,它们组合在一起形成功能性句子。

The spirit of Demeter's Law is that, given an object reference or class, you should avoid accessing the properties of a class that's more than one sub-property or method away since that will tightly couple the two classes, which might be unintended and can cause maintainability problems.

Fluent interfaces are an acceptable exception to the law since they're meant to be at least somewhat tightly coupled as all the properties and methods are the terms of a mini-language that are composed together to form functional sentences.

帝王念 2024-07-12 19:03:11

是的,尽管你必须对这种情况采取一些实用主义。 我总是把德墨忒尔法则作为指导方针,而不是规则。

当然,您可能很想避免以下情况:

CurrentCustomer.Orders[0].Manufacturer.Address.Email(text);

也许替换为:

CurrentCustomer.Orders[0].EmailManufacturer(text);

随着我们越来越多的人使用 ORM,它通常将整个域呈现为对象图,为特定对象定义可接受的“范围”可能是一个想法。 也许我们应该采用得墨忒耳定律来建议您不应将整个图映射为可到达的。

Yes, although you have to apply some pragmatism to the situation. I always take the Law of Demeter as a guideline as opposed to a rule.

Certainly you may well want to avoid the following:

CurrentCustomer.Orders[0].Manufacturer.Address.Email(text);

perhaps replace with:

CurrentCustomer.Orders[0].EmailManufacturer(text);

As more of us use ORM which generally presents the entire domain as an object graph it might be an idea to define acceptable "scope" for a particular object. Perhaps we should take the law of demeter to suggest that you shouldn't map the entire graph as reachable.

晨与橙与城 2024-07-12 19:03:11

你的例子没有问题。 毕竟,您正在旋转、加水印等……始终是相同的图像。 我相信您一直在与 Pipeline 对象对话,因此只要您的代码仅依赖于 Pipeline 的类,您就不会违反 LoD。

There's no problem with your example. After all, you're rotating, watermarking, etc... always the same image. I believe you're talking to a Pipeline object all the while, so as long as your code only depends on the class of the Pipeline, you're not violating LoD.

[旋木] 2024-07-12 19:03:11

从本质上讲,对象不应该公开其内部结构(数据),而应该公开用于操作内部结构的函数。

考虑到这一点,Fluent API 要求对象对其数据进行处理,而不是询问其数据。

这并不违反任何德墨忒尔法则。

At heart, an object shouldn't expose its internals (data) but rather expose functions to operate with the internals.

Taking that into account, Fluent API is asking the object to work on something with its data, not asking its data.

And that doesn't violate any of the Laws of Demeter.

断念 2024-07-12 19:03:11

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) 正如 Good Ol' Phil Haack 所说: 德墨忒尔定律不是一个点计算练习

1) It does not violate it at all.

The code is equivalent to

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) As Good Ol' Phil Haack says : The Law of Demeter Is Not A Dot Counting Exercise

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文