DDD Structural validation using JQAssistant and Maven 10 Sep 2015
If you are familiar with Domain Driven Design (DDD) you might have already tried to validate the structure of your application during your build process. By validating I mean making sure that no dependency was introduced between layers of your application that should not access eachothers.
In the following article I will show you how to do that using JQAssistant and maven for a Java application.
Typicaly if you are using DDD you have defined layers inside your backend code. Those layers can vary a little bit between intrepretation of the DDD concept, as dependencies between layers.
In my case here are the layers of my application backend. Arrows represent authorized dependencies between layers. For example Interfaces depend on application. It means you can use application objects inside an object of the interfaces layer.
JQAssistant typical flow is composed of 2 steps : scanning and analysing.
During the scanning phase JQAssistant is able to flag your files with some labels. It uses Neo4j as the underlying database to save those information. Neo4j is a graph database. So each of your file is in fact seen as a Node in the Neo4j database. It is also able to create relationships between those nodes. Typically JQAssistant is able to scan your classes files and create dependency relationships between them. This is the relationship we will use to validate our DDD structure.
JQAssistant can be used inside maven (hopefully for the poor JAVA developers we are). Here is an extract of my pom.xml
The important thing to note is the groups. Inside each group, you will be able to define certain rules to be tested on your scanned files.
Now is the time to define our rules. They should be defined inside an xml file inside the JQAssistant directory that should be located under your app directory (next to your pom.xml).
The first thing we want to do is to flag our classes depending on the layer they belong to. This is pretty easy, we just need to create a concept. Here is the concept that will add the flag DDD_Interfaces to my class if its package is part of the packages interfaces.
We create the other concepts for the application, domain and infrastructure layers.
Constraints are the rules that will be tested on your files (nodes).
Again it is quite easy. Here is the constraint that checks if some classes inside the interfaces layer (flagged as DDD_Interfaces thanks to our previous concept) depends on classes inside the domain layer. If we find some, it means our ddd structure has been violated. Because we set the flag failOnViolations to true inside our pom.xml the maven goal will fail and your maven build will fail as well.
Here is my final rules.xml if you are too lazy to write it yourself :) Note that I have another rule part of the default group. It is just to illustrate the notion of group.
It is probably possible to use only one constraint to test everything. But I had no time to try to improve my rule.xml. It also makes it more readable for a beginner like me in cypher.