You first need to import the library in Gradle.
implementation com.tngtech.archunit:archunit:1.0.0 (1)
1 |
For real projects you should describe your dependencies in a catalog file. |
The definition of a validation test is easy.
Below an architectural rule to respect the Domain-Driven Design concepts in our project [1].
@AnalyzeClasses(packages = "net.tangly.erp.collaborators") (1)
public class DomainRules { (2)
static final String SERVICES = "Services";
static final String PORTS = "Ports";
static final String DOMAIN = "Domain";
@ArchTest
static final ArchRule layersRule = layeredArchitecture().consideringAllDependencies()
.layer(DOMAIN).definedBy("..domain..")
.layer(SERVICES).definedBy("..services..")
.layer(PORTS).definedBy("..ports..")
.whereLayer(DOMAIN).mayOnlyBeAccessedByLayers(SERVICES, PORTS)
.whereLayer(SERVICES).mayOnlyBeAccessedByLayers(PORTS)
.whereLayer(PORTS).mayNotBeAccessedByAnyLayer();
}
1 |
Declare the root package for the bounded domain classes.
The bounded domain should be defined as a Java module. |
2 |
The domain rules class shall be declared as part of the domain library of your application. |
These rules are defined in the library component and enforced in all the Bounded Domains we implement through the following unit tests.
@AnalyzeClasses(packages = "net.tangly.erp.collaborators")
public class ArchitectureTest { (1)
@ArchTest
static final ArchTests domainRules = ArchTests.in(DomainRules.class); (2)
}
1 |
The class is located in the unit test folder and will be executed with JUnit 5 as part of the unit test CI step. |
2 |
Import all the rules defined in the domain rules class and apply them to the bounded domain collaborators. |
We can insure architectural constraints to all bounded domains defined in a product.
The constraints are defined only once in a common module.
The huge advantage is the integration of architectural validations in the continuous integration pipeline [2] [3].
No expensive human activities are required to enforce these rules [4].