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