这是得墨忒耳法则的一个很好的例子吗?

Is this a good example of Law of Demeter?

我正在备考,不知是否正确理解得墨忒耳法则。从本质上讲,我理解 Demeter 法则旨在通过减少 classes 彼此之间的依赖来放松耦合,并且不明确地放弃 classes 如何获取某些信息。这是在引用“只与您的直接朋友交谈”中得出的结论。我想出了这个简化的例子:

如果我们有一个 class 棋盘,并且我们的游戏场上有游戏棋子,例如想要找出哪些棋子移动了,一种直观的方法是这样写:

Board.getGamePiece(p).getMovement();

但这违反了得墨忒耳法则。因此,我们通过简单地编写以下内容将该任务委托给 getMovement 方法:

Board.getMovement(p);

我的理解是否正确,我的解释有没有错误?我有点不确定如何在这里使用术语“委托”,它在我的示例中使用正确吗?

我认为您理解了这个想法,但我不确定您的示例是否真的有意义。在棋盘游戏的背景下,棋盘很难不关心可能的动作! (所以在这里应用 Demeter 是没有意义的,因为董事会已经可以访问运动 class)。

I have understood Law of Demeter correctly

这是一个模糊的、不科学的原则。它不像万有引力定律,也不像语言规范。您将其提升为二元概念(代码要么违反它,要么不违反)。这是双重错误:

  • 见仁见智,深浅不一。没有“此代码违反它,而此代码未违反”之类的事情。
  • 这是一个准则,而不是规则。有时编写许多人都同意的代码完全违反了这一原则,但它却是正确的编写方式(从某种意义上说,它会导致最有效、最容易理解、最容易测试和最容易修改的代码)未来的变更请求)。

Board.getGamePiece(p).getMovement();

Board.getMovement(p);

这是我的意见,但是,任何从 LoD 的角度对这些行发表评论都是意见,如果有人试图告诉你它不是,他们错了:)

这些在 LoD 的意义上是完全相等的,并且此代码(任一版本)都完全没问题。

要点是:两者都意味着您知道存在游戏棋子这样的东西并且棋子可以移动的概念。这两行代码也以某种方式或形式 return a Movement,所以在任何一种情况下,这段代码不仅知道 'game pieces exist' 和 'they can move',而且还 'and this is what a move looks like and how to interact with it'.

board.getMovement(p)你一无所获。

去掉这些模糊的概念,你就会有所收获。如果您将 board.advance() 编写为一种方法,它通过询问每个棋子它想要进行的运动来应用 1 回合的事件,然后移动所有棋子并进行处理,例如有些棋子现在已经损坏,那么你现在涉及的概念要少得多: 运行 board.advance() 的代码知道有一个棋盘,还有转弯这样的东西,你可以前进一圈

代码不需要知道碎片的存在,或者它们可以移动。

T运行slating 'LoD' 到 java 就像任何看起来像这样的代码: a.method1().method2() 必然是 LoD 的中断,好吧,请随意这样做。然而,如果你把它混在一起,结果是:

  1. a.method1().method2() 破坏了 LoD。
  2. 破坏 LoD 是糟糕的代码风格,导致难以维护代码。
  3. 因此,a.method1().method2() 是错误代码。

然后你搞砸了某个地方。不是;严格应用此原则将导致您复制大量代码并从程序员级别添加更多依赖项(现在 board 中的代码需要比您不知道的更多地了解哪些部分可以做什么'不要这样做)。

关于这种模糊的风格指南,这让我们得到了另一个教训:它们几乎总是直接竞争。如果您尝试 'optimize' 以获得 LoD,您很可能会失败大量其他规则,例如 DRY。

最终目标是编写可维护的代码。这比尝试应用一些死记硬背的概念(例如 'avoid a.x().y()')要困难得多。编程很难。