ArchUnit: самый элегантный способ проверить, зависят ли пакеты друг от друга

У меня есть две посылки com.myapp.foo а также com.myapp.bar и я хочу знать самый элегантный способ явно проверить, если эти два пакета (и только те, как есть еще com.myapp.XX) не зависят друг от друга.

Вот что я сейчас имею (работает великолепно):

    SliceAssignment packagesFooAndBar = new SliceAssignment() {
        @Override
        public String getDescription() {
            return "foo and bar";
        }

        @Override
        public SliceIdentifier getIdentifierOf(JavaClass javaClass) {
            if (javaClass.getPackageName().startsWith("com.myapp.foo")) {
                return SliceIdentifier.of("foo");
            }
            if (javaClass.getPackageName().startsWith("com.myapp.bar")) {
                return SliceIdentifier.of("bar");
            }
            return SliceIdentifier.ignore();
        }
    };
    @ArchTest
    final ArchRule packagesFooAndBarNotDependOnEachOther = SlicesRuleDefinition
        .slices()
        .assignedFrom(packagesFooAndBar)
        .should()
        .notDependOnEachOther();

Есть ли более элегантный способ, может быть, без использования SliceAssignment? Спасибо!

0 ответов

Я бы, наверное, использовал два правила.

@ArchTest
final ArchRule fooShouldNotDependOnBar = ArchRuleDefinition
.classes()
.that().resideInAnyPackage("com.myapp.foo")
.should().onlyDependOnClassesThat()
.resideOutsideOfPackage("com.myapp.bar");

@ArchTest
final ArchRule barShouldNotDependOnFoo = ArchRuleDefinition
.classes()
.that().resideInAnyPackage("com.myapp.bar")
.should().onlyDependOnClassesThat()
.resideOutsideOfPackage("com.myapp.foo");

Если вы хотите записать то же самое в одном правиле без пользовательских классов, следующее должно работать. Я не уверен, что назвал бы его элегантным, поскольку он кажется немного сложным. Вероятно, есть лучшие способы записать это в одном правиле.

@ArchTest
final ArchRule packagesFooAndBarNotDependOnEachOther = SlicesRuleDefinition
    .slices()
    .matching("com.myapp.(*)")
    .should()
    .notDependOnEachOther()
    .ignoreDependency(
        JavaClass.Predicates.resideOutsideOfPackages("com.myapp.foo", "com.myapp.bar"),
        DescribedPredicate.alwaysTrue())
    .ignoreDependency(
        DescribedPredicate.alwaysTrue(),
        JavaClass.Predicates.resideOutsideOfPackages("com.myapp.foo", "com.myapp.bar"))
    );

Правило сначала соответствует всем прямым подпакетам com.myapp. ПервыйignoreDependency затем исключает все зависимости от классов за пределами данных пакетов (чтобы, например, com.myapp.xx получить доступ com.myapp.foo). СекундаignoreDependency исключает все зависимости от данных пакетов к любому внешнему пакету (например, чтобы разрешить com.myapp.foo получить доступ com.myapp.xx).

Другие вопросы по тегам