LoginSignup
0
0

More than 3 years have passed since last update.

ArchUnit 実践:依存関係を逆転した Layered Architecture ではインフラストラクチャ層は他の層のインターフェイスにのみ依存できる

Last updated at Posted at 2020-12-09
// 実行環境
* AdoptOpenJDK 11.0.9.1+1
* JUnit 5.7.0
* ArchUnit 0.14.1

アーキテクチャテストのモチベーション

2 日目の ArchUnit 実践:依存関係を逆転した Layered Architecture のアーキテクチャテスト の、依存関係を逆転した Layered Architecture では、インフラストラクチャ層は依存関係の最上位に存在します。これは対象のクラス(インターフェイス)に代わって技術的詳細を実装するためであり、インフラストラクチャ層のクラスが他の層に依存してよいのは、そのインターフェイスを実装する場合のみです。他の層の具象クラスへの依存は禁止されるべきです。

アーキテクチャテストの実装

package com.example;
 
import com.tngtech.archunit.base.DescribedPredicate;
import com.tngtech.archunit.core.domain.JavaClass;
import com.tngtech.archunit.core.domain.JavaClasses;
import com.tngtech.archunit.core.importer.ClassFileImporter;
import com.tngtech.archunit.core.importer.ImportOption;
import org.junit.jupiter.api.Test;

import static com.tngtech.archunit.lang.syntax.ArchRuleDefinition.classes;

class ArchitectureTest {

    // 検査対象のクラス
    private static final JavaClasses CLASSES =
            new ClassFileImporter()
                    .withImportOption(ImportOption.Predefined.DO_NOT_INCLUDE_TESTS)
                    .importPackages("com.example");

    @Test
    void インフラストラクチャ層のクラスは他の層のインターフェイスにのみ依存できる() {
        classes().that().resideInAPackage("com.example.infrastructure..")
            .should()
            .onlyDependOnClassesThat(new DescribedPredicate<>("他の層のインターフェイス") {
                /**
                 * @param clazz 依存先のクラス
                 * @return 依存先のクラスが他の層の具象クラスである場合、false
                 */
                @Override
                public boolean apply(final JavaClass clazz) {
                    if (! clazz.getPackageName().startsWith("com.example")) {
                        // サードパーティーライブラリなどへの依存はOK
                        return true;
                    }
                    if (clazz.getPackageName().startsWith("com.example.infrastructure")) {
                        // 同じインフラストラクチャ層のクラスへの依存はOK
                        return true;
                    }
                    if (clazz.isInterface()) {
                        // 他の層のインターフェイスへの依存はOK
                        return true;
                    }

                    return false;
                }
            })
            .check(CLASSES);
    }
}
0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0