It can be hard to grasp what software architecture is as it encompasses a wide range of theoretical and practical disciplines. It ranges from describing how we structure our code to drawing diagrams for sequences, flows and relationships between elements in our applications. It can be used to describe what already is and the current landscape of our software, but it can also define our intentional software architecture and how our software ought to be structured. Both often tend to deviate from reality, which we will get to under the "Architectural drift and erosion" section.
The aim of this post is not to describe the perfect software architecture but rather define what software architecture is.
Disclosure: Bear in mind that some of the links in this post are affiliate links and if you go through them to make a purchase I will earn a commission. Keep in mind that I link these companies and their products because of their quality. The decision is yours, and whether or not you decide to buy something is completely up to you.
Defining software architecture
The book "Documenting Software Architectures: Views and Beyond" contains the following definition of software architecture which describes it as:
"The set of structures needed to reason about the system, which comprises software elements, relations among them, and properties of both." - from Documenting Software Architectures by Clements et al.
Most who read the above definition likely think the same, that it is a very broad definition, but it is a short and yet precise definition. As software architecture can describe different aspects and levels of software the word "structures" can be anything from structuring a database, a suite of applications or the layers in your application. "Reason about" is great as this is often what we need when we look at diagrams, we need to understand what we are about to build or understand how something was built. The wording "reason about" leaves the level of detail open, as there is no exact level of detail that must be given, but it should be enough to make sense of the architecture you are looking at.
"Software elements, relations among them and properties" is general enough that it can describe anything from classes to a suite of applications and how they interact. What properties need to be documented for the architecture to be descriptive is again up to what is needed to reason with it. For a description of how several services interacts a description of their APIs and how they are consumed, would be a good list of properties. For classes their public members would be a good list of properties as well.
The book "Software Architecture In Practice" contains the following definition:
"The software architecture of a program or computing system is the structure or structures of the system, which comprise software elements, the externally visible properties of those elements, and the relationships among them." - from Software architecture in practice by Bass et al.
The above definition mentions a structure of "software elements", these are the same as the previous definition, which could be: classes, applications APIs etc. It is mentioned that software architecture describes "the externally visible properties of those elements, and the relationships between them". Here there is a difference from the previous definition as this definition has an emphasis on "visible properties". This is to omit details that are not related to their interaction. Functionality within elements that is solely internal, meaning that it is of no interest to the outside is not part of the software architecture. This is known as implementation details, omitting these is known as hiding implementation details. A simple example would be the use of public and private access modifiers.
From the above you can see that Software architecture is not "just" a diagram, a diagram of your system is just visualisation of it. What properties and relations that need to be described in your software architecture is up to you, but it should make you and others able to reason about it.
Examples of software architecture
If you believe the two previous descriptions were too high level with their "elements", "relations", "properties" and "structures", then here are a few practical examples of what could be known as software architecture:
Three-tier software architecture
The three tier software architecture is known by many and likely one of the first things developers learn about when first developing software. This is a software architecture pattern which can be used to structure your applications. Here is a short definition of it:
Three-tier architecture is a client-server software architecture pattern in which the user interface (presentation), functional process logic ("business rules"), computer data storage and data access are developed and maintained as independent modules, most often on separate platforms." from Three Tier Client/Server Architecture: Achieving Scalability, Performance, and Efficiency in Client Server Applications by Eckerson, Wayne W.
This is an architectural description of a single application with 3 layers and how the layers interact with one another. The structure emphasises that the interface only interacts with the business logic and never directly with the data layer, the same is true the other way around. This is often the standard on how to model applications but it has many variations, like a four-tier software architecture.
An example of the Three-tier software architecture from researchgate can be seen below:
It is composed of three layers:
- Presentation: Handles the presentation of the application and the interactions of the user.
- Business: Handles the business logic of the application - the "heart" of the application. It is easier to think of the business layer in the context of the presentation layer, as an application may have several presentations (web, app, API etc.) but they likely reuse the same business logic.
- Data Access: This is where the data of the application is persisted - often in a database.
Unified modelling language
A UML diagram is a standard way to visualise a system. UML has several ways to do this, but it basically fall into two categories:
- Behaviour diagrams: describes what happens in the system and sometimes in which order. This has a high emphasis on interaction, from what starts the flow to what the end result is, two honourable mentions are use case diagrams or sequence diagrams.
- Structure diagram: We previously mentioned the three-tier software architecture which would be a great example for a structure diagram. The interface, the business rules and the data layer are three structures that interact. Another example would be a class diagram.
There are many types of UML diagrams as can be seen here. UML is a great tool to visualise your software architecture.
The three tier software architecture pattern describes how to model a single application using technical layers but not how to model your business or how several applications interact. Some architectural patterns tackle this and commonly known these days is the microservice pattern:
"the microservice architectural style is an approach to developing a single application as a suite of small services, each running in its own process and communicating with lightweight mechanisms, often an HTTP resource API. These services are built around business capabilities and independently deployable by fully automated deployment machinery." from martinfowler.com by James Lewis and Martin Fowler
Microservices is a pattern used to achieve a high level of availability, scalability, modifiability and testability aimed at creating an architecture for a whole system.
What do these three have in common?
They are all about structures, their relations and visualisation of these. They also show that architecture is found at different levels, it can be a simple class diagram or a large suite of services. The three examples are very different and this is one of the reasons it can be hard to define what software architecture exactly is and why it can seem "abstract". This is also the reason why the previous definitions can be perceived as being broad, as they encompass many different practices.
Architectural drift and erosion
Visualisations and descriptions of architecture are often different from the actual reality. The documentation may not be updated or is non-existing, as Thanos from Marvel would put it "reality is often disappointing". Over time our [architectures drift or erode](Architectural drift and erosion) which are two terms to describe what happens in all software architectures:
- Architectural drift: happens when design does not keep up with development or development does not keep up with design. If new features or cross cutting concerns are never documented the architecture has drifted from its original capabilities. It can also be that it is documented but not implemented, as the software does not meet the requirements of the design. Overall this can be seen as the architectural design and the actual implementation has deviated from one another - they have drifted apart and need to catch up.
- Architectural erosion: has a more common name "hacks". Implementations that cause Architectural drift may be well written and fit in with the overall design of the system. Architectural erosion on the other hand does not fit in, an example could be calling the data layer directly from the interface in a three tier architecture or introducing services in a microservice architecture with several business capabilities. Overall it comes from implementations that do not live up to the spirit and intentions of the architectural design.
Which is worse? Both can make it hard to make changes, architectural drift is mostly about handling what is unknown and finding the true state of affairs. Architectural erosion can be hard to untangle and rewriting the code base takes time which can be very costly.
Wrapping it up
I hope this post helped you understand software architecture better. As mentioned previously this post does not try to define what a good software architecture is or how you should design your system, it merely defines what software architecture is and aims to describe it with examples. I hope you enjoyed this post, please let me know what you think in the comments down below!
Here are the two books previously mentioned in this post. The first is "Software Architecture in practice" which I used excessively when writing my master thesis on microservices:
The second is "Documenting Software Architectures: Views and Beyond", I have not read this book but I see it mentioned here and there: