Enforce your Java architecture with ArchUnit
Sometimes follow the architecture only coding is hard, either by the developers or by jump from one layer to another, ie, controller calling the persistence š and so on.
We can catch the scenarios above in a code review, or using a library to automate this task (I like this option š).
1. Examples of architecture (Fundamentals of Software Architecture)
1.1. Monolithic
- Layered architecture (target here)
- Pipeline architecture
- Microkernel architecture
1.2. Distributed
- Service-based architecture
- Event-driven architecture
- Space-based architecture
- Service-oriented architecture
- Microservices architecture
2. Hands on
This article will be based on the Java project 16-bits-zero-to-hero, available on my GitHub.
The project is monolithic, yes the good and old monolithic. This should be the first approach in your project.
Using the screenshot below, we can identify how the project was built.
1st ā Project layers
2nd ā The Unit Test, our guardian for a better architecture
3rd ā Gradle build file
4th ā The dependency to archUnit
Giving another view to the project. Based on the architecture, we cannot call the persistence from the presentation, and vice-versa.
Only the Business layer can talk with the Presentation and Persistence layers.
2.1. UT (Unit test)
With only one UT you can set your guardian to guarantee the system architecture.
In our setup, first we need to inform the UT to not consider the test package. If in your case you have any exception, please add to setup too.
Then there is a silly test, saying that any web package is accessible for any class inside the web package.
And the last, and the more important is about the layers, where we control the layers, outstanding š®.
2.2. Failed tests
Just to brake the test, letās change the MovieController and inject the MovieRepository and run the test. As expected, it should fail.
1st ā Was added a repository instance on presentation layer ā ļø
2nd ā The check is made by ArchUnit
3rd ā The failed test, since is not allowed to have the repository in this class
4th ā The failed reason
2.4. Passed tests
The way to fix, is to revert the code, ie, donāt inject or use the persistence layer inside the web.
3. Tech stack
- Java ā openJDK11
- Gradle ā 7.4
- ArchUnit ā 0.23.1
- SpringBoot ā 2.6.3
- JUnit 5ā5.8.2
4. Conclusion
This phrase makes sense to me, when talking about doing things. āIf I have to remember, Iāll forgetā. Because of this, having a library to help us to maintain the cohesion, and the architecture is marvelous. The library configuration is easy and fast and has a great documentation.