IntelliJ IDEA: Dependency Analysis with DSM
DSM stands for Dependency Structure Matrix – a method for exploring dependencies between program parts (modules, classes, etc.), and provides a compact matrix representation of a project. It helps you visualize the dependencies between the parts of a project and highlights the information flow within a project.
When working on complex software projects it’s especially important to track dependencies between project parts. You might encounter too complicated relationships, or cyclic dependencies, that may seriously affect application performance and behavior, or even impede further project development. IntelliJ IDEA has adopted the DSM technology to provide easy reviewing and resolving of potential problems in project structure.
Letâ€™s take a closer look at the DSM. To view the dependency matrix of your project, select Analyze | Analyze Dependency Matrix from the main menu and specify the desired analysis scope. If your project class files are out-of-date, IntelliJ IDEA will ask you whether you want to compile a project before continuing the DSM analysis. It is recommended to compile the project to avoid the analysis resulting in incomplete or incorrect data.
When ready, the DSM View is opened in a new window, enabling to examine dependencies. Letâ€™s discover what we can learn from the DSM view.
In our example there is a typical DSM view with one of the rows selected. The row headers represent program structure. Everything is collapsed now and only modules are shown. When expanded, the header is tree-like, allowing you to dig into program packages. The column headers are the same as the corresponding row headers. Thus they are not shown in order to save space. Instead, different visual aids are used on the row headers.
Here we can learn the following:
- The selected row and corresponding column are highlighted to visualize row dependencies.
- The ellipsis in the cell means that the maven-core module has many (more than 99) dependencies on maven-project module.
- The column shows the dependencies of the selected row.
- The row shows the dependencies on the selected row.
- This means that the maven-project module has 16 dependencies on maven-settings module.
- Various shades correspond to the number of dependencies. The more dependencies there are the bluer the corresponding cell is.
And what about dashes and color annotations? This is quite obvious also.
- Color annotations help to visualize row dependencies at a glance.
- This green annotation means that maven-core depends on maven-project.
- This yellow annotation means that maven-project depends on maven-profile.
- The dashes on the diagonal correspond to self dependencies which are not shown.
Thus, when we select a row, green annotations show dependent modules, while the yellow ones show modules on which the selected module depends.
Dependency matrix becomes more convenient, if you remember one simple mnemonic rule â€“ all dependencies always â€œflowâ€ from Green to Yellow.
At this moment weâ€™ve only selected one of the rows. Letâ€™s select some cell to explore the dependencies indicated in it.
For example, cell #1 is one of interest. Weâ€™ve selected it, and again, we can see some color annotations. They mean that maven-project has 16 dependencies on maven-settings. The symmetrical cell (cell #2) shows dependencies in the other direction – in this case zero.
You might notice that instead of alphabetically sorting rows, DSM view sorts dependencies in a special way: classes, which are used most, are moved to the bottom. In a project with good structure this creates a triangular shape in the lower left half of the matrix.
Letâ€™s drill down a little bit and expand some cell. For example, we want to take a closer look at dependencies between maven-core and maven-error-diagnostics. Corresponding cell is shown below.
We double click it to view the expanded dependencies.
If the project contains mutual dependencies, called cycles, weâ€™ll simply detect them while exploring the DSM view.
Cyclic dependencies are shown in red. In our example, this means that the lifecycle and * are both dependent on each other, as well as plugin and usability.
Such dependencies require much more attention, and you may need to investigate them narrowly. Integrated advanced code navigation will help you to jump directly to the code which requires your attention. Just right-click the dependency and choose Find Usages for Dependencies on the context menu.
All usages will be shown in the corresponding tool window.
While exploring dependencies you may find that some part of your project deserves more attention and should be discovered in detail while the rest of the project is not of interest at the moment. In such case, you can limit the scope of your DSM to the selected rows, or dependencies.
Now, structure of any complex project, with thousands of Java classes, spreads out before your eyes.