ArchUnits layeredArchitecture 规则不包含字段
ArchUnits layeredArchitecture rule doesn't include fields
我们通过一些 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,这不会抛出异常 class:
package com.acme.layer1
import static com.acme.layer3.SOME_LABEL
public class x {
...
}
我们的期望是,从任何其他层中的 layer3 访问字段也应该抛出异常。
或者有其他方法可以检查吗?
我的回答基于以下假设:com.acme.layer3.SOME_LABEL
是 constant expression,类似于 public static final String SOME_LABEL = "..."
Compile-time 常量在编译期间内联。如果你的代码看起来像
String label = SharedConstants.SOME_LABEL;
然后编译后的字节码包含 SharedConstants.SOME_LABEL
的精确值。字节码中仍然没有对该字段的引用。 (The Static Final Inline Trap)
ArchUnit 通过分析字节码收集所有信息,另见 ArchUnit User Guide。因为字节码中没有关于SharedConstants.SOME_LABEL
的信息,所以ArchUnit不知道这个访问。
总结:这是 ArchUnit 和所有其他仅依赖于字节码的库的限制。
我们通过一些 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,这不会抛出异常 class:
package com.acme.layer1
import static com.acme.layer3.SOME_LABEL
public class x {
...
}
我们的期望是,从任何其他层中的 layer3 访问字段也应该抛出异常。 或者有其他方法可以检查吗?
我的回答基于以下假设:com.acme.layer3.SOME_LABEL
是 constant expression,类似于 public static final String SOME_LABEL = "..."
Compile-time 常量在编译期间内联。如果你的代码看起来像
String label = SharedConstants.SOME_LABEL;
然后编译后的字节码包含 SharedConstants.SOME_LABEL
的精确值。字节码中仍然没有对该字段的引用。 (The Static Final Inline Trap)
ArchUnit 通过分析字节码收集所有信息,另见 ArchUnit User Guide。因为字节码中没有关于SharedConstants.SOME_LABEL
的信息,所以ArchUnit不知道这个访问。
总结:这是 ArchUnit 和所有其他仅依赖于字节码的库的限制。