Java 这是德米特定律的一个好例子吗?

Java 这是德米特定律的一个好例子吗?,java,oop,decoupling,design-principles,law-of-demeter,Java,Oop,Decoupling,Design Principles,Law Of Demeter,我正在准备口试,我想知道我是否正确地理解了德米特定律。本质上,我已经理解了Demeter定律的目的是通过减少类之间的依赖性来放松耦合,并且不明确地给出类如何获得某些信息。这句话的结尾是“只和你的直系朋友说话”。我提出了一个简化的例子: 如果我们有一个类板,在我们的游戏场上有游戏块,例如,想要找出哪些块移动了,一个直观的方法是写下如下内容: Board.getGamePiece(p).getMovement(); 但这违反了德米特的法律。因此,我们只需编写以下命令,即可将该任务委托给getMov

我正在准备口试,我想知道我是否正确地理解了德米特定律。本质上,我已经理解了Demeter定律的目的是通过减少类之间的依赖性来放松耦合,并且不明确地给出类如何获得某些信息。这句话的结尾是“只和你的直系朋友说话”。我提出了一个简化的例子:

如果我们有一个类板,在我们的游戏场上有游戏块,例如,想要找出哪些块移动了,一个直观的方法是写下如下内容:

Board.getGamePiece(p).getMovement();
但这违反了德米特的法律。因此,我们只需编写以下命令,即可将该任务委托给getMovement方法:

Board.getMovement(p);

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

我认为你对此想法感到惊讶,但我不确定你的示例是否真的有意义。在棋盘游戏中,棋盘很难不考虑可能的移动!(因此,在这里应用Demeter可能没有意义,因为董事会已经可以访问Movement类)

我正确地理解了德米特定律

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

  • 这是一个意见的问题,这是灰色的阴影。没有“此代码违反了它,而此代码没有”这样的事情
  • 这是一个指导方针,不是规则。有时,编写许多人都认为完全违反了这一原则的代码是正确的编写方法(从这个意义上讲,它会导致最高效、最容易理解、最容易测试,并且在未来的更改请求面前最容易修改)
Board.getGamePiece(p.getMovement()

vs

Board.getMovement(p)

这是我的观点,但是,那么,从LoD的角度对这些行的任何评论都是观点,如果有人试图告诉你这不是,他们就错了:)

从LoD的意义上讲,它们是完全相等的,并且该代码(任何一个版本)都是完全正确的

要点是:两者都意味着你知道游戏中有一个棋子,棋子可以移动。这两行代码还以某种方式或形式返回一个
移动
,因此在这两种情况下,该代码不仅知道“游戏碎片存在”和“它们可以移动”,而且还知道“这就是移动的样子以及如何与之交互”

通过编写
board.getMovement(p)
,您一无所获

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

代码不需要知道片段是否存在,或者它们是否可以移动

将“LoD”转换为java的任何代码如下:
a.method1().method2()
必然是LoD的一个突破,好吧,请随意这样做。但是,如果您将其混合在一起,结果是:

  • a.method1().method2()
    中断LoD
  • 破坏LoD是一种糟糕的代码风格,导致代码难以维护
  • 因此,
    a.method1().method2()
    是错误的代码
  • 然后你把某个地方搞砸了。事实并非如此;严格应用这一原则将导致您复制大量代码,并从程序员级别添加更多依赖项(现在
    board
    中的代码需要比不这样做时更多地了解片段可以做什么)

    这让我们得到了关于这种模糊风格指导方针的另一个教训:它们几乎总是直接竞争。如果您试图“优化”LoD,则很可能会失败很多其他规则,例如DRY


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

    如果您有一个更好的具体例子,说明如何违反德米特法,以及如何根据设计原则进行修复,请发布:)