Managing Architecture Debt with Dependency Structure Matrix
Technical Debt is a hot topic in all software development projects that over time gets more sophisticated as source code grows gradually. There are plenty of tools analyzing technical debt that basically concentrates on code quality. Architecture debt being subpart of technical debt is not that easy to determine, since there are no automated tools available as in case of technical debt.
When determining Architecture debt the one should look into architectural anti-patterns that are coupled in source code. Here are common architectural anti-patterns that need to be determined and eliminated:
- Unstable Interfaces: these are generally APIs or entry points to a system which have bunch of dependent components. Little changes in these interfaces cause lots of headache in all dependent components.
- Modularity violation: software systems should be structured in modular way. This means together changeable components should be structured in same modules to avoid inter-modular dependencies. If changes in one module influences other modules drastically the one should investigate what are root causes of these instability.
- Unhealthy inheritance: this happens when super class depends on its child class or caller class depends on both super and child instances.
- Cyclic dependencies: this happens when for example component A depends component B which depends on component C, that in return depends components A which creates cyclic dependency. This should be avoided through Dependency Inversion Principle.
- Package cycle: multiple packages or plugins depend on each other chaotically rather than forming hierarchical dependency
- Crossing: these are God classes that depend on multiple other classes, and on other hand numerous different classes depend on this specific class
In order to avoid this kind of Architecture anti-patterns Software Architects should take into account implementing S.O.L.I.D. principles, GoF design Patterns, Coupling principles/Component Principles.
Below is given UML of exemplary cashflow Spring Boot Application. You can have a look at my git repo for source code as well. As you can see the project is structured in three base packages: …api*, …core*, …database*** in layered pattern. …api* package is responsible for exposing restful APIs to external callers, …core* packages gather all business relevant code inside and …database* concentrates on database layer.
![](https://cdn-images-1.readmedium.com/v2/resize:fit:800/1*lVnmjhF8SfhV6SnPHJTa5g.png)
After examining UML diagram of Cashflow Application let us generate Dependency Structure Matrix of the system. I have used Jarchitect tool for matrix generation but there are lots of alternatives: such as DSM support of Intellij or Ndepend. Columns and rows represent Java classes in src folder of Spring Boot app which are structured in symmetrical way. Column 8 which is IncomeService corresponds to row 8 that is same class/interface. Figures in cells represent static dependency import between classes. For example: Column 12 (ConverterServiceImpl.java) has 1s in rows: 4 ,5 ,10 which means this class impleements ConverterService, ExpenseConverterService, Service.
![](https://cdn-images-1.readmedium.com/v2/resize:fit:800/1*n8Ag1nvEC-khWSecm_fcdA.png)
In order to find Architecture Debt through DSM, the one should look for:
- cyclic calls: Class A calling B and B calling A back
- crossing: cells with big numbers mean lots of dependencies
- numbers should allocate around diagonal line: that means classes are high cohesive
- the more chaotic allocation of numbers in matrix means dependency structure is unsafe
- Evaluate S.O.L.I.D principles by looking into numbers of columns that hold interfaces
If you are interested in more Software Architecture topics take a look at my other articles.
Relevant Articles: