The Law of Demeter Doesn't Mean One Dot

The following text is a partial translation of the original English article, performed by ChatGPT (gpt-3.5-turbo) and this Jekyll plugin:

你可能已经听说过那个30年前的迪米特法则(LoD)。最近有人问我对它的看法。不仅仅是我怎么看,还有如何让对象保持小并遵循迪米特法则。根据这个法则,我们不允许像book.pages().last().text()这样做。相反,我们应该使用book.textOfLastPage()。这让我感到困惑,因为我强烈不同意。我认为第一个结构在面向对象编程中是完全有效的。所以我做了一些研究,想找出这个法则是否真的是一个法则。我发现这个法则是完美的,但在面向对象编程领域的普遍理解却是错误的(并不令人惊讶)。

面向对象编程:客观风格感,K.Lieberherr, I.Holland, and A.Riel, OOPSLA’88 Proceedings, 1988.

这是它被引入的地方。让我们看看它文字上的意思(在那个PDF文档中找第3节)。

假设这是一个Java类:

根据 LoD(迪米特法则),对四个不同的 hello() 方法的四次调用都是合法的。我问自己,什么是非法的呢?毫不奇怪,答案是:a.x.hello()。那是非法的。直接从另一个对象访问属性,然后与之交流是不被法律允许的。

但是我们不会那样做。我们在谈论的是 book.pages().last().text()。在这一系列的方法调用中,我们没有访问任何属性。我们请求我们的对象为我们构建新的对象。法律对此有什么说法呢?让我来阅读并引用一下:

换句话说,方法调用book.pages()返回的对象Pages是一个完全有效的对象,可以使用。然后,我们可以在它上面调用方法last()并获得一个Page对象,然后调用方法text()等等。这是一个完全有效的场景,根本没有违反法律,正如我所预料的那样。

那么,这个关于法律的共识是从哪里来的呢?为什么Wikipedia称之为”一点法则”,并说”对象应该避免调用另一个方法返回的成员对象的方法”?这完全与原始论文相反!到底发生了什么?

答案很简单:getter方法。

大多数面向对象编程开发人员认为,大多数返回任何内容的对象方法都是getter方法。而getter方法实际上和直接访问对象属性没有区别。这就是为什么Wikipedia实际上说”不要直接访问属性,并且,由于大多数方法都是getter方法,也不要触碰它们,傻瓜”。

看到这一点真是令人难过。

所以,底线是,德米特法则根本不反对方法链。当然,它反对getter方法和直接属性访问。但是,谁不反对呢,对吧?

Translated by ChatGPT gpt-3.5-turbo/42 on 2023-12-15 at 06:35

sixnines availability badge   GitHub stars