Правило слоистой архитектуры ArchUnits не включает поля
Мы проверяем нашу программную архитектуру по некоторым правилам ArchUnit.
Одним из них является тест для нашей многоуровневой архитектуры.
Это хорошо работает для методов. Если мы получим доступ к методу layer3 из layer1, мы получим исключение.
Но если получить доступ к полю, объявленному в layer3 из layer1, это не вызовет исключения.
.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 в любом другом слое должен вызвать исключение. Или есть другой способ проверить?
1 ответ
Мой ответ зависит от предположения, что com.acme.layer3.SOME_LABEL
это постоянное выражение, как public static final String SOME_LABEL = "..."
Константы времени компиляции встроены во время компиляции. Если ваш код выглядит
String label = SharedConstants.SOME_LABEL;
тогда скомпилированный байт-код содержит точное значение SharedConstants.SOME_LABEL
, Там нет ссылки на это поле в байт-коде. ( Статическая финальная встроенная ловушка)
ArchUnit собирает всю информацию путем анализа байт-кода, см. Также Руководство пользователя ArchUnit. Потому что нет информации о SharedConstants.SOME_LABEL
в байт-коде ArchUnit не знает об этом доступе.
Итак, это ограничение ArchUnit и всех других библиотек, которые зависят только от байт-кода.