Software Architecture is not what you think it is…
There are many definitions floating about software architecture and even more notions that people have on it.
Yet, few really grasp what that concept means.
It's a shame though because to be a successful software architect, you need to understand what true software architecture is.
To be an in-demand software architect, you need to understand what the true value of that role is.
But before we even get there, you need to understand what software architecture is and what it isn't.
If we go searching for the term, Wikipedia provides a nice ChatGPT-like 🤖 definition -
"Software architecture is the set of structures needed to reason about a software system and the discipline of creating such structures and systems. Each structure comprises software elements, relations among them, and properties of both elements and relations"
Sounds legit. Though, I think that we can do better.
Let us postulate that Software Engineering is the processes and practices that go into building software. In its simplest form, this is the process of coding an application and designing its internal components.
Now, when we build our software - designing it, coding it, and testing it, that is not really enough for producing a quality, production-ready, application, is it?
Something's missing… 🤔
Perhaps not for the simplest of applications, but for most production-level applications out there, the reality is that they also have to work with other applications. They have to coexist in a certain environment with other things and hopefully, to play nice with them.
We are not only concerned with our application being coded to spec.
We are also concerned with it being scalable, resilient, fault-tolerant, responsive. We want it to be easy to maintain and transparent to observe.
We probably also need it to work correctly with other applications.
In other words, this system must have certain non-functional requirements (NFRs). Some of these requirements will reflect in your code. Some within your infrastructure configuration -
while others with your choice of technology.
Moreover, you somehow need to ensure that the system you've built answers the requirements of your actual product.
Otherwise, what's the point of building it in the first place?
So what we need then is a wider perspective.
We need an understanding of how code, infrastructure, configuration, business, product, non-functional requirements and other factors all intertwine.
The definition of software architecture then becomes
Software Architecture is the practice of getting a wider perspective of your application than with software engineering alone. This involves both technical and non-technical elements. The end result is a clear understanding of that application's limitations, its ability to satisfy both functional and non-functional requirements, and its place within the wider ecosystem and environment.
Now, there are many facets and sub-streams to "software architecture".
🔵 Enterprise Architecture
🔵 Solution Architecture
🔵 Technical Architecture
🔵 Application Architecture
🔵 … and many more
They all fall under the umbrella definition above, and they all have their place.
These are all pieces and scopes of your software architecture. They deal with different levels of abstraction but they all converge in that they connect the technical aspects of software to its business and organizational aspects.
Now, there are three key parts of software architecture.
Architectural Characteristics
NFRs
Tradeoffs
Architectural Characteristics
These are properties of your system as a whole.
For example:
🔵 Scalability
🔵 Responsiveness
🔵 Observability
🔵 Testability
🔵 Availability
and so on…
These are also called 'ilities' because of the suffix many of them share.
More on these in my article Architectural Tradeoffs - What Are Architectural Characteristics.
There are guidelines for achieving or emphasizing this or that architectural characteristic within your system.
Also, focusing on some of these characteristics may come with a tradeoff of foregoing other characteristics..
For instance, focusing on scalability will usually increase the complexity and testability of a system as you are adding new mechanisms to support its scaling.
Non Functional Requirements
On the other hand, NFRs (Non Functional Requirements) or Cross-Functional Requirements are often talked about interchangeably with Architectural Characteristics.
They are slightly different concepts though.
If architectural characteristics are the overall attributes of your system, NFRs are specific requirements that are based on one or more of these characteristics.
For example, let's imagine that we are focusing on system performance, scalability, and responsiveness.
These are the characteristics we want to ensure that the system has.
Now, some NFRs closely tied to these characteristics could be something like:
👉 The system currently must support 100 TPS (transactions per second)
👉 Within a year, the system must support up to 30,000 TPS
👉 The system must have a response time of under 100ms 99% of the time.
In other words, NFRs drive the focus on a particular set of architectural characteristics.
Architectural Tradeoffs
Lastly, architectural tradeoffs are the pros and cons of selecting this or that technical option or making a specific architectural decision. These are based on architectural characteristics and directly affect your NFRs.
Let's go through a concrete example.
Say you're building a system for displaying stock quotes. As you can imagine, this system should probably have the ability to display stock quotes in more or less real-time. In other words, any change in pricing should be immediately reflected in your system.
So the architectural characteristic you are interested in here is one of both resilience as well as correctness or "freshness" of data.
The data displayed to the user must be the latest we have.
One NFR then might be - display a stock quote with no more than 2ms of delay between the data that was received from the financial record system and the system that displays this data.
An architectural tradeoff might then be additional complexity to minimize delay and increase the resilience of the application. This might involve, for example, running an active-active failover infrastructure with real-time syncing of data.
I go a lot more in depth in these tradeoffs in my Architecture Tradeoffs series.
As a software architect, many of the conversations you will have with both technical and non-technical stakeholders will involve these 'ilities' and NFRs.
Explaining and socializing these in both technical and non-technical terms is a key part of software architecture.
Now, here's a crucial point about software architecture. This is one of these determinants of an organization's failure or success from a technical system's perspective.
Software architecture ALWAYS takes place. The problem is that, often, it happens without any one actively guiding, shaping, and nurturing it.
This was especially glaring during the past few years (2018 - 2022), which have been forgiving with how organizations spent their money.
VCs were throwing money at almost anything with a founder and a plan to disrupt , digitize, or scale….something.
Large corporations were pumping funds into growth both in terms of staff and number of poorly thought-through and daring projects.
There was an opportunity for improving, fixing, rectifying old and lingering problems.
Instead, so many organizations just sprinted forward with new, often poorly thought through, initiatives.
The landscape has then changed in late 2022-early 2023, and most of these exciting initiatives have been canned or thrown out.
Yet, most of the pre-existing problems with processes and systems remain and have now been magnified.
Many of these problems were directly caused by how systems were architected.
🔹 Limited scale.
🔹 Brittle integrations.
🔹 Poorly designed applications.
🔹 Locking into the wrong vendors.
🔹 Hacky workarounds - because, you know - "We're focusing on growth now. Just make it work - and put this as technical debt!"
Now, you might think that all of this is the result of bad architectural decisions.
That's only part of the story though...
❓ How were these decisions made?
❓ "Why" were these decisions made?
❓ What could we have done to make better decisions?
Here's the real problem that I have come across time after time.
👉 So many software organizations simply let architecture happen to them.
❌ "We don't have time to invest in design/architecture"
❌ "Our clients depend on our speed to market"
❌ "We don't need software architects"
❌ "We need an estimate now"
❌ "We're agile!"
And on and on and on….
The problem is that
You will ALWAYS have a software architecture effort happen and take place.
The only difference is that it will happen implicitly.
This is one of the foundations of software architecture that is so often missed.
Software engineering always happens actively. You have to code your application for it to come into existence. Obviously.
However, when it comes to software architecture, it does not have to be as explicit. As you build applications and connect them, there is an architecture being shaped by itself - driven by software engineering.
Think of it as a higher order level of abstraction.
It is the layer that connects systems, processes, non-functional requirements, and different software characteristics with your code base.
That layer is the layer of software architecture, and the reason it is sometimes hard to define, is precisely because it lives on a different level of abstraction than software engineering.
Yet, it is both a part of software engineering and is outside of it because it deals with concepts that are arguably not necessarily a core part of software development or engineering.
So let's summarize.
What is Software Architecture?
It is the practice of getting a wider perspective of your application than with software engineering alone. This involves both technical and non-technical elements such as architectural characteristics, Non Functional Requirements, and the interlinking of the technical and business sides of the project. Moreover, it is a discipline that is tightly connected with software engineering but at the same time, transcends it to tackle higher-order concerns.
Comments