It can be hard to grasp what software architecture exactly 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 architecture and how our software ought to be structured. Both often tends to deviate from the reality, but we will get to that under "Architectural drift and erosion".
In this post I do not answer what a good software architecture is, but I bring two definitions of it.
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.
I believe most who read this definition think the same, that it is a very broad definition, but it is actually the shortest yet most precise definition I have come across. As architecture can describe different aspects and levels of software architecture 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 to be open, as there is no exact level of detail that must be given, but it should be enough to make reason 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 needs 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.
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.
In the above definition a structure of "software elements" is mentioned, these are the same as the previous definition, which could be: classes, applications APIs and so on. 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 architecture. This is known as implementation details, omitting these is known as hiding implementation details.
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 needs to be described in your architecture is up to you, but it should make you and others able to reason about the it.
Examples of software architecture"
If you believe the two previous descriptions were too high level with their "elements", "relations", "properties" and "structures" I will here give a few practical examples of what could be known as software architecture:
The three tier architecture is known by many and likely one of the first things developers learn about architecture. This is a software architecture pattern which can be used to structure your applications. I like the following 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 emphasis that the interface only interacts with the business logic and never directly with the data layer, the same is true the other way around. I have often found this to be a standard on how to model applications in the companies I have worked for.
Unified modeling language
UML diagrams is a standard way to visualise a system. UML has several ways to do this, but they basically fall into two categories:
- Behavior 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. Some honorable mentions are use case diagrams or sequence diagrams.
- Structure diagram: we previously mentioned the three-tier architecture which would be a great example for a structure diagram. The interface, the business rules and the data layer are three structures that interacts. 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 architecture.
The three tier 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. This is also the reason why the previous definitinos can be perceived as being broad, as they encompasses 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 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 in the software does not meet the requirements of the design. Over all 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 does 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. However 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 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: