Java 使用Guice和";得墨忒尔定律“;

Java 使用Guice和";得墨忒尔定律“;,java,guice,pmd,law-of-demeter,Java,Guice,Pmd,Law Of Demeter,“打破”得墨忒尔定律”中的一个微不足道的例子。至少是它的意思 public class BillingModule extends AbstractModule { @Override protected void configure() { bind(TransactionLog.class).to(DatabaseTransactionLog.class); bind(CreditCardProcessor.class).to(PaypalCreditCardPro

“打破”得墨忒尔定律”中的一个微不足道的例子。至少是它的意思

public class BillingModule extends AbstractModule {
  @Override 
  protected void configure() {
    bind(TransactionLog.class).to(DatabaseTransactionLog.class);
    bind(CreditCardProcessor.class).to(PaypalCreditCardProcessor.class);
    bind(BillingService.class).to(RealBillingService.class);
  }
}
PMD在下一行标记警告
可能违反Demeter法(方法链
电话)

使用
@SuppressWarnings(“PMD.LawOfDemeter”)
抑制此警告可以吗?还是需要使用其他方法

澄清

通过一些简单的方法,可以将fluent界面转换为经典界面:

fasten(TransactionLog.class, DatabaseTransactionLog.class);
紧固的可能实现方式

private <M, N extends M> void fasten(final Class<M> dependency, final Class<N> realization){
    fastenTo(bind(dependency), realization);
}

private <M, N extends M> void fastenTo(final AnnotatedBindingBuilder<M> binder, final Class<N> realization){
    binder.to(realization);
}
它不是
bindActor(actorClass).qualified(name).with(props)
,而是
bindActor(actorClass,name,props)

我知道Guice要复杂得多,可以有更多的参数和组合,然而,有人创建了包装库来取代Guice中的fluent接口吗?有人写过什么吗?或者,有人对流利的语言感到满意吗

此外,我还阅读了有关fluent界面和Demeter法则的文章和帖子。只有几篇文章,显然不是来自主流男性。他们中的一些人写道fluent是好的,这里必须违反德米特定律,他们中的一些人写道fluent接口不好,他们中的一些人写道fluent没有违反德米特定律。社区没有严格的愿景

不过,这个问题是关于Guice的,而不是一般的“流畅”界面

这样的“编码规则”检查工具。。。是关于执行规则的

他们带来了一个默认的规则集,但使用这些工具的本质是:他们应该做你想让他们做的事

换句话说:我们不能告诉你什么是适合你的。如果你;你周围使用这个工具的团队也同意:“我们理解这个警告;我们认为压制它是好的”;那你都准备好了。你不需要SO社区的认可;你希望负责你项目的人同意“正确的事情”

我在这里看到的唯一一个“真正”的问题是:决定是否要在代码中添加大量这样的注释;或者,您应该调整PMD规则集

还有一些个人的2美分:我确实认为“得墨忒尔法”实际上是一条重要的规则。我正在使用python开发一个小型cmdline工具;我最初故意违反了LoD。3天后,我开始后悔那个决定了。但是看看你的代码示例;我不会宣布这是一个值得考虑的LoD违规行为(所以:压制对我来说没问题)

或者,有人对流利的语言感到满意吗

Javadoc中提到了fluent接口的意图(重点是我的):

Guice使用嵌入式领域特定语言(EDSL)来帮助您简单易读地创建绑定

流畅的语法有很大的好处,因为您可以获得简单的活页夹代码,读起来几乎像自然语言:

bind(TransactionLog.class).to(DatabaseTransactionLog.class);
一般来说,在软件工程中,在做出决策时,您必须平衡优势和劣势。再次从同一个javadoc读取:

这种方法(EDSL)对于整体可用性来说是非常好的,但是它的成本很小:很难通过读取方法级别的javadocs来学习如何使用绑定EDSL

它接着承认了流畅语法的一个缺点,即
Binder
javadoc变得稍微不透明。可能违反德米特法是另一个不利因素

此外,我还阅读了有关fluent界面和Demeter法则的文章和帖子。只有几篇文章,显然不是来自主流男性。他们中的一些人写道fluent是好的,这里必须违反德米特定律,他们中的一些人写道fluent接口不好,他们中的一些人写道fluent没有违反德米特定律。社区没有严格的愿景

就这样吧!有可能存在适合不同性格的多种方法

您可能应该注意到关于C#中的扩展方法是否违反封装的类似争论。请参阅Eric Lippert的精彩引用。

一个流畅的API并不一定违反Demeter定律,因为并非所有的链调用都违反了Demeter定律

Demeter定律规定,您可以访问所处对象内部的任何内容、获得的方法参数或在调用过程中创建的任何对象

因此:

bind(TransactionLog.class).to(DatabaseTransactionLog.class)
很好。您没有得到以前存在的任何内容,而是创建了一个新绑定。解除引用应用于(可能)新对象(新绑定生成器或其他任何对象)


德米特定律基本上规定,不应访问其他对象的内部字段。只要您不这样做,您可以拥有一个呼叫链,只要您愿意。

协议流程如何?是一些知名人士写的文章,还是社区的推荐。例如,如果您认为团队必须遵守法律,并且我认为在Guice绑定的情况下必须禁止这种行为。除了“我想是的”之外,我还能用别的方法证明吗?我会做什么:做一些研究,比如列出这些出版物,然后开一个公开会议。你最终会得到一份包含你的决定的书面文件。我也是这样做的,但似乎没人太在意它。关于这个问题的文章很少。还有任何关于“得墨忒尔法”和吉塞的文章。谢谢你的回答,这很有帮助。@AndriyKuba这并不是Guice特有的,它适用于任何“流畅”的界面。有很多文章都在谈论关于流畅接口的德米特定律。@AndriyKuba我想我的观点是,在我看来,流畅接口一般不会违反法律
default <T extends akka.actor.Actor> void bindActor(java.lang.Class<T> actorClass,java.lang.String name)

default <T extends akka.actor.Actor> void bindActor(java.lang.Class<T> actorClass,java.lang.String name, java.util.function.Function<akka.actor.Props,akka.actor.Props> props)
bind(TransactionLog.class).to(DatabaseTransactionLog.class);