-
Notifications
You must be signed in to change notification settings - Fork 170
Open
Description
Currently in our project, we are migrating from a spaghetti ball to a modular structure. We find 2 rules very useful in our case:
- It really helps if the dependencies are explicitly referring to a specific named interface, never a whole module.
- Every module HAS to explicitly specify it's allowed dependencies, even if there are none
We use these three archunit tests to enforce this:
1. Enforce only named interfaces in allowed dependencies
@Test
void allowedDependenciesShouldAlwaysBeNamedInterfaces() {
var rootPackage = importedClasses.getPackage("com.something");
var violations = rootPackage
.getSubpackages()
.stream()
.filter(pkg ->
Arrays.stream(pkg.getAnnotationOfType(ApplicationModule.class).allowedDependencies()).anyMatch(
allowedDependency -> !allowedDependency.contains("::")
)
)
.map(
pkg ->
pkg.getDescription() +
" has a module name in the `allowedDependencies` instead of a named interface. Only use specific named interface dependencies. E.g. instead of \"core\" use \"core :: configuration\""
);
assertThat(violations)
.as(
"Because that way we can keep modulith as strict as possible to prevent accidental additional dependencies in the future"
)
.isEmpty();
}
2. Enforce explicit allowed dependencies for every module
@Test
void applicationModulesShouldSpecifyTheirDependencies() {
var defaultAllowedDependencies = "[%s]".formatted(ApplicationModule.OPEN_TOKEN);
var rootPackage = importedClasses.getPackage("com.something");
var violations = rootPackage
.getSubpackages()
.stream()
.filter(pkg ->
Arrays.toString(pkg.getAnnotationOfType(ApplicationModule.class).allowedDependencies()).equals(
defaultAllowedDependencies
)
)
.map(
pkg ->
pkg.getDescription() +
" does not set `allowedDependencies` in the @" +
ApplicationModule.class.getSimpleName() +
"annotation"
);
assertThat(violations)
.as("Because a module should explicitly declare it's dependencies so that it is immediately visible")
.isEmpty();
}
Would it be of interest for spring-modulith to include these as optional configuration options in the library? I'd be open to try and create a PR for this if this is something that would be a welcome addition.
Metadata
Metadata
Assignees
Labels
No labels