【问题标题】:Is this a good example of Law of Demeter?这是得墨忒耳法则的一个很好的例子吗?
【发布时间】:2021-01-06 16:41:46
【问题描述】:

我正在准备口试,我想知道我是否正确理解了得墨忒耳法则。从本质上讲,我已经理解得墨忒耳法则旨在通过减少类之间的依赖来放松耦合,并且不明确地透露类如何获取某些信息。这在引用“只与你的直系朋友交谈”中得出结论。我想出了这个简化的例子:

如果我们有一个班级棋盘,并且我们的比赛场地上有游戏棋子,例如,想要找出哪些棋子移动了,那么直观的方法就是这样写:

Board.getGamePiece(p).getMovement();

但这违反了得墨忒耳法则。因此,我们只需编写以下代码即可将该任务委托给 getMovement 方法:

Board.getMovement(p);

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

【问题讨论】:

  • 如果你有更好的具体例子说明如何违反得墨忒耳定律以及如何按照设计原则进行修复,请发布:)

标签: java oop decoupling design-principles law-of-demeter


【解决方案1】:

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

【讨论】:

    【解决方案2】:

    我已经正确理解得墨忒耳法则

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

    • 这是一个见仁见智的问题,它是灰色阴影。不存在“此代码违反了它,而此代码没有”之类的东西。
    • 这是一个指导方针,而不是规则。有时编写许多人会同意的代码完全违反了这一原则,但它仍然是编写它的正确方法(从某种意义上说,它导致最有效、最容易理解、最容易测试和最容易在面对未来的变更请求)。

    Board.getGamePiece(p).getMovement();

    Board.getMovement(p);

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

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

    重点是:两者都意味着您了解存在诸如游戏棋子之类的东西并且棋子可以移动的概念。这两行代码也以某种方式或形式返回Movement,所以在任何一种情况下,这段代码不仅知道“游戏棋子存在”和“它们可以移动”,而且“这就是移动的样子喜欢以及如何与之互动”。

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

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

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

    将 'LoD' 翻译成 java 的任何代码如下:a.method1().method2() 必然是 LoD 的中断,好吧,请随意这样做。但是,如果您将其混为一谈,最终结果为:

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

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

    这让我们又学到了关于这种模糊的风格指南的另一个教训:它们几乎总是直接竞争。如果您尝试针对 LoD 进行“优化”,您很可能会失败大量其他规则,例如 DRY。

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2016-06-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多