Pretty graphs... what do they mean?
A quote from: Using Dependency Models to Manage Complex Software Architecture.[PDF]
An approach to managing the architecture of large software systems is presented. Dependencies are extracted from the code by a conventional static analysis, and shown in a tabular form known as the ‘Dependency Structure Matrix’ (DSM). A variety of algorithms are available to help organize the matrix in a form that reflects the architecture and highlights patterns and problematic dependencies.
[Neeraj Sangal, Ev Jordan Lattix, Inc. and Vineet Sinha, Daniel Jackson Massachusetts Institute of Technology.]
How must I read them?
Actually very simple, see figure 1:
Image from: Evolution Analysis of Large-Scale Software Systems Using Design Structure Matrices & Design Rule Theory [PDF]
Why should I care?
You should care about dependencies..! as an architect and as an developer. Dependencies can make code difficult to read and maintain, dependencies can introduce bugs, dependencies and how they're structured are the key to how well an app holds up as it changes over time. [Code-Dependency Analysis]
If the tasks are tightly coupled, with many cyclic dependencies, the pipeline will stall frequently, and tasks will need to be repeated because of dependencies on tasks that follow them.
Within a previous post I used a very simple UI app to demonstrate the code metrics from VS2008. Let's see how those Dependency Matrixes look like.
First implementation: Visual Studio Drag and Drop.
We can see, EmployeeForm [user-interface] has a dependency on Employees and Employee [Business layer] and Employees has a dependency with Employee. The last one is obvious, the first one is not good. When we need to change Employees or Employee we also have to change the user-interface. This doesn't look like a big impact, but this is a very very small application, can you imaging the amount of work when there are hundreds of forms.
The second implementation didn't changed anything to our dependency matrix. We removed the generated events and let them point the same methods. We introduced some reuse in the events but didn't changed anything at the dependencies.
In the third implementation we introduced some kind of controller and although it looked promising in the code metrics table in turned out dramatic in the dependency matrix.
Why? the EmployeesController has a dependency to EmployeeForm, Employees and Employee [not good] but also the EmployeeForm has a dependency to the EmployeesController. So, with this implementation we introduced a cyclic dependency.
Assemblies that have cyclic dependencies are typically more difficult to unit test, maintain and understand. Cyclic dependencies make it more difficult to predict what the effects of changes in one assembly are on the rest of the system.
See also the quote in the "Why should I care?" paragraph.
Fourth implementation "adapter pattern together with the command pattern and observer". A lot of classes, a lot of colored boxes... but when you study on it, it looks good. The EmployeeForm only depends on commands and adapters, adapter only on commands and the controller only on employee and employees.
The last implementation, where we introduced some interfaces looks even more promising. [take a look and figured it out]
Dependency matrixes a great for code review, refactoring, analyze, design review and to see the evolution of your software. So, a must in every application lifecycle.
There are already "dependency"tools available, NDepend and Lattix for example which do a great job. I'm curious if this tool will get to them same level of maturity.