【问题标题】:ArchUnits layeredArchitecture rule doesn't include fieldsArchUnits layeredArchitecture 规则不包含字段
【发布时间】:2019-05-27 07:42:13
【问题描述】:

我们通过一些 ArchUnit 规则检查我们的软件架构。

其中之一是对我们分层架构的测试。

这适用于方法。 如果我们从 layer1 访问 layer3 的一个方法,我们会得到一个异常。

但如果从 layer1 访问 layer3 中声明的字段,则不会抛出异常。

   .layer("layer1").definedBy("com.acme.layer1")
   .layer("layer2").definedBy("com.acme.layer2")
   .layer("layer3").definedBy("com.acme.layer3")
   .whereLayer("layer3").mayNotBeAccessedByAnyLayer()
   .whereLayer("layer2").mayOnlyAccessedByLayers("layer3")
   .as("Respect the layered architecture");

如果我们将一个字段从 layer3 导入到 layer1 类,这不会抛出异常:

package com.acme.layer1

import static com.acme.layer3.SOME_LABEL

public class x {
   ...
}

我们的期望是,在任何其他层访问来自 layer3 的字段也应该引发异常。 或者有其他方法可以检查吗?

【问题讨论】:

    标签: archunit


    【解决方案1】:

    我的答案取决于com.acme.layer3.SOME_LABELconstant expressionpublic static final String SOME_LABEL = "..." 一样的假设

    编译时常量在编译期间内联。如果你的代码看起来像

    String label = SharedConstants.SOME_LABEL;
    

    那么编译后的字节码包含SharedConstants.SOME_LABEL精确值。字节码中没有对该字段的引用。 (The Static Final Inline Trap)

    ArchUnit 通过分析字节码收集所有信息,另见ArchUnit User Guide。因为字节码中没有SharedConstants.SOME_LABEL的信息,所以ArchUnit不知道这个访问。

    总而言之:这是 ArchUnit 和所有其他仅依赖于字节码的库的限制。

    【讨论】:

      猜你喜欢
      • 2021-06-27
      • 2020-02-26
      • 2018-02-02
      • 1970-01-01
      • 2015-04-10
      • 2013-03-18
      • 2016-08-22
      • 2016-07-26
      相关资源
      最近更新 更多