Правило слоистой архитектуры ArchUnits не включает поля - PullRequest
0 голосов
/ 27 мая 2019

Мы проверяем нашу программную архитектуру по некоторым правилам 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 class:

package com.acme.layer1

import static com.acme.layer3.SOME_LABEL

public class x {
   ...
}

Мы ожидаем, что доступ к полям из layer3 в любом другом слое должен вызвать исключение. Или есть другой способ проверить?

1 Ответ

0 голосов
/ 27 мая 2019

Мой ответ зависит от предположения, что 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 и всех других библиотек, которые зависят только от байт-кода.

...