Why use code?

This page provides an overview of why Structurizr encourages you to use code as a way to create software architecture models.

Static text

There has been a trend over the past few years towards text-based tooling, with popular examples including PlantUML and WebSequenceDiagrams. With these tools, the diagram source is provided as text using a simple domain-specific language, which the tool then visualises. Structurizr Express does the same thing.

These tools are fantastic for quickly creating simple static diagrams, but they are typically used in a standalone manner, are not necessarily connected with the code they describe and can therefore become out of date very easily.

Architecture description languages

The idea of using text isn't new, and attempts have been made in the past to create a more formalised approach using something called an architecture description language. Some, like Darwin for example, offer a text-based language that you can use to describe the architecture of a software system. Diagrams are then created using supporting or additional tooling such as Graphviz. Using a text-based language is certainly appealing for us as software developers, but architecture description languages have never really seen mainstream adoption.

Code

The software architecture model used by Structurizr is represented as a JSON document, which can be easily created by writing code using the open source Structurizr for Java or Structurizr for .NET client libraries. Creating a software architecture model as code provides a number of interesting opportunities for creating the model and communicating it.

In essence, rather than writing a static text file, you're writing one or more short programs that create a software architecture model during their execution. Using code rather than a static domain specific language makes it much easier to automatically extract model elements from a codebase and manipulate the model in a number of ways. Here's what a typical "software architecture as code" program might do.

Why use code to create a software architecture model?

Isn't code a verbose and cumbersome way to create diagrams?

Although using code to create simple diagrams might seem verbose and cumbersome when compared to static text-based approaches, the real power becomes evident when you start to create a model of your software system rather than a disconnected collection of static diagrams.

An API for creating the model

With Structurizr, the Java and .NET client libraries provide a number of classes representing people, software systems, containers and components. In addition to providing a set of data structures to represent elements in the software architecture model, these classes also provide an API that allow you to easily create a hierarchical software architecture model, and the relationships between the elements in that model. This also makes it impossible to, for example, add components directly to a software system because the API won't allow it. The result is a model with a degree of structure and integrity.

An API for creating views

Similarly, the Java and .NET client libraries provide a number of classes to represent the various views that can be created with Structurizr, complete with a set of rules as to which elements can and can't be added to those views. This prevents you accidentally, for example, adding components to a system context view.

In addition, creating the views using code allows you to easily do things like create a system context diagram for a software system, where only the immediately related elements are added. For example (with Java):

SystemContextView view = views.createSystemContextView(softwareSystem, "SystemContext", "...");
view.addNearestNeighbours(softwareSystem);

Imagine you're building a web application based upon the web-MVC pattern. Given that even a relatively small web application might consist of tens or hundreds of components, a single component diagram is likely to be too cluttered to be useful. Instead, using code, you can create one component diagram per slice through the web application. For example (with Java):

Set<Component> controllers = webApplication.getComponents().stream()
    .filter(c -> c.getTechnology().equals(SpringComponentFinderStrategy.SPRING_MVC_CONTROLLER))
    .collect(Collectors.toSet());

for (Component controller : controllers) {
    ComponentView view = views.createComponentView(webApplication, controller.getName(), "...");
    view.addAllElements();
    view.removeElementsThatCantBeReachedFrom(controller);
}

With static text-based approaches, you would likely need to manually create each and every diagram. With code, it's just a matter of creating one component view per web application controller and adding/removing elements based upon the elements and their relationships in the model.

Automatically find components in a codebase

The other major benefit of using code as an architecture description language is that you can write algorithms to help you automatically identify components in an existing codebase, using techniques like reflection or static analysis. This is exactly what the ComponentFinder class in the Java and .NET client libraries is designed to do. It means that just a few lines of code are needed to create a model of the components that reside in a given codebase. For example (with Java):

ComponentFinder componentFinder = new ComponentFinder(
    webApplication,
    "org.springframework.samples.petclinic",
    new SpringComponentFinderStrategy(
            new ReferencedTypesSupportingTypesStrategy(false)
    ),
    new SourceCodeComponentFinderStrategy(new File(sourceRoot, "/src/main/java/"), 150));
componentFinder.findComponents();

Code like this will scan a codebase to identify components (based upon the set of rules that you provide) and the relationships between those components.

Benefits of using code to create software architecture models

In summary, some benefits of using code to create software architecture models are:

  • Code is familiar: Code is familiar to us as software developers, so let's take advantage of this rather than creating another language with which to represent a software architecture model.
  • Flexibility for creating models: In addition to manually writing code to create a software architecture model, we can also write code to extract architectural concepts (e.g. components) from our production codebase using techniques such as reflection, introspection and static analysis.
  • Flexibility for visualising models: Writing code to create the views of a software architecture model provides you with the ability to slice and dice the model as needed. For example, showing all components for a large system will result in a very cluttered diagram. Instead, you can simply write some code to programmatically create a number of smaller, simpler diagrams; perhaps one per vertical slice, web controller, user story, etc. You can also opt to include or exclude any elements as necessary.
  • Versionable: Since the models are code, they are also versionable alongside your codebase.
  • Living documentation: The code to generate the model can be integrated with your automated build system to keep your models up to date; providing accurate, up-to-date, living software architecture diagrams that actually reflect the code.

In essence, Structurizr is an implementation of an executable architecture description language, specifically focussed around the C4 model.