Search code examples
archunit

How to differentiate usage and inheritance in a layered architecture?


I'm trying to validate the following dependencies:

relationships

Source

In this picture, red relationships are forbidden, green relationships are allowed:

  • no class in the adapter package can inherit from a class in the port package;
  • any class in the adapter package can use (e.g. have a field) a class in the port package;
  • no class in the service package can use (e.g. have a field) from a class in the port package;
  • any class in the service package can inherit a class in the port package;

If possible I'd like to add these validations to Layered Architecture.

Thank you.


Solution

  • LayeredArchitecture considers all dependencies between layers. You cannot forbid inheritance, but allow access – nor vice versa. I recommend to define individual specific rules instead:

    @ArchTest
    ArchRule adapter_should_not_inherit_from_port = noClasses()
        .that().resideInAPackage("….adapter")
        .should().beAssignableTo(JavaClass.Predicates.resideInAPackage("….port"));
    
    @ArchTest
    ArchRule service_should_not_access_port = noClasses()
        .that().resideInAPackage("….service")
        .should().accessClassesThat().resideInAPackage("….port");