This exercise uses JDepend to explore the component dependencies in an example of clean architecture.
Download the code for this exercise and unzip the archive.
This will create and exercise7
directory, containing a subdirectory
named jdepend
, in which you will find the JDepend tool and a script
to run it.
Within the exercise7
directory, enter this command to clone the
repository of the example application:
git clone https://github.com/mattia-battiston/clean-architecture-example.git example
cd into the example
subdirectory and build the example application with
./gradlew build
cd into the jdepend
subdirectory and run JDepend in ’text mode’ on
the example application, like so:
./jdepend ../example/application report.txt
The first argument to this script is a directory under which compiled code can be found for the application that we are analyzing. The second argument is a filename for the report that JDepend will generate.
Examine report.txt
in a text editor.
For each package of the application, JDepend has reported: total number of classes; number of concrete classes; number of abstract classes; afferent coupling (which we describe in COMP5911M as fan-in); efferent coupling (fan-out); abstractness; instability; and distance from the main sequence. See the lecture material for further discussion of these metrics.
In addition to reporting values for fan-in and fan-out, JDepend also lists incoming and outgoing dependencies, under the headings ‘Used By’ and ‘Depends Upon’, respectively.
Run JDepend’s GUI, like so:
./jdepend ../example/application
This variant displays the same information as report mode, but in a GUI. The upper panel lists each package for which JDepend has identified fan-out (efferent) dependencies. The lower panel lists each package for which JDepend has identified fan-in (afferent) dependencies.
Beside each package name in either panel are the metrics computed for that package: CC = number of concrete classes; AC = number of abstract classes; Ca = afferent coupling, i.e. fan-in; Ce = efferent coupling, i.e. fan-out; A = abstractness; I = instability; D = distance from main sequence; V = volatility.
You can double-click on a package name to expand it and see a list of the outgoing or incoming dependencies.
First, get more familiar with the example application by consulting the README in its GitHub repository, or by studying the associated slide deck. You may also find it useful to examine the source code itself.
Now examine the JDepend report, or the information displayed in the GUI.
Look at the package associated with the ‘Get Capacity’ use case. You
should be able to see that it depends on a number of packages, but only
one of them, com.clean.example.core.entity
, is part of the application.
If you examine the latter, you’ll see that it depends on only two packages,
neither of them part of the application.
Now look at the packages that depend on the ‘Get Capacity’ use case. Notice how they relate to data providers and REST entry points – i.e., components on the periphery of the architecture.
If you examine the packages for the other use cases, you’ll observe the same pattern of dependency.
Now consider the metrics of abstractness (A), instability (I) and distance
from main sequence (D). Look at the values of these metrics for all of the
com.clean.example
packages. Try plotting abstractness vs instability,
following what is discussed in the lectures. You should see a reasonable
inverse correlation between A and I, with most packages lying reasonably
close to the ‘main sequence’ line and a couple at some distance from it.
libxslt
and
graphviz
packages.
Generate the dependency graph for the example application like so:
./depgraph ../example/application deps.png
This will generate the graph as a a PNG image in the file deps.png
.
If you would prefer an SVG file instead, use .svg
as the
filename suffix.
View the graph in your preferred image or SVG viewer.
□