Components vs classes

If you've ever tried to use a static analysis, modelling or diagramming tool to automatically generate meaningful diagrams of your codebase, you will have probably been left frustrated. After all, the resulting diagrams tend to include too much information by default and they usually show you code-level elements rather than those you would expect to see on a software architecture diagram. Let's look at a quick example.

Auto-generating a UML class diagram

The "Spring PetClinic" application is a sample codebase used to illustrate how to use the Spring framework to build web applications in Java. It's a typical layered architecture consisting of a number of web MVC controllers, a service containing business logic and some repositories for data access, along with some domain and util classes too. Here is the diagram that the Spring team uses to summarise the software architecture.

If you download a copy of the GitHub repository, open it in your IDE of choice and visualise it by drawing a UML class diagram of the code, you'll get something like this.

Auto-generating a UML class diagram

This diagram shows all of the classes/interfaces and all of the relationships between them. The properties and methods are hidden from view because they add too much noise to the picture. This isn't a complex codebase by any stretch of the imagination, but the diagram is showing too much detail.

Filtering the classes

Let's remove those classes that aren't relevant to having an "architecture" discussion about the system. In other words, let's only try to show those classes that have some structural significance. In concrete terms, for this particular codebase, this means excluding the model (domain) and util classes.

Filtering the classes shown

After a little rearranging, this diagram is much better and we now have a simpler diagram with which to reason about the software architecture. We can also see the architectural layers (controllers, services and repositories).

Highlighting components

In order to show the true picture of the dependencies on this diagram, we need to show the interface and implementation classes for the service and repositories, plus any other supporting classes (e.g. row mappers, etc). To simplify the diagram, we could treat the ClinicService and each of the *Repository things as a "component", by collapsing the interface and implementation classes (plus any supporting classes) together on the diagram.

Collapsing the interface and implementation to highlight components

As this example illustrates, we can think of a component as simply being a collection of implementation classes behind an interface. And rather than diagramming the component internals, this diagram zooms out slightly to show these components and how they are related to one another. This still leaves us with the ability to zoom in to see the internals of a component if we need to, but that view by default is often too detailed, especially for systems with any degree of size and complexity. This is one of the key differences between Structurizr and many other diagramming tools - it's about highlighting components rather than classes.

Extracting components

One of the goals of Structurizr is to help software teams create this type of component diagram automatically, based upon the code. Here is the live version of the Spring PetClinic component diagram, which was created using the Structurizr for Java client library (here is the source code). Double-click a component and you'll be taken to the source code that represents that component on GitHub.

The Structurizr for Java client library includes a ComponentFinder and a number of component finder strategies that help you extract components from a codebase. Since every software system is different, these pluggable strategies let you create an appropriate set of rules that define how components are structured in your codebase.