Software Architecture: Building Systems That Fit Your Needs
Software architecture is crucial for robust applications. Discover its role in avoiding scalability issues and ensuring efficient performance.
Why care about Software Architecture?
Imagine a scenario in which you and a small team work on a simple e-commerce application without giving much thought to your software architecture. With only a few users initially, you may not encounter any issues, and adding new features can be done quickly without much ado. When your app attracts more and more users, you may experience crashes under high load as scaling aspects have not been considered from the start. Over time, new features might even worsen the situation as they may require different additional resources that become scarce in varying use cases. Hence, each new feature may break your application at some other place, and finding workarounds may turn your code slowly into a historically grown mess with deferred technical debts and no options for deeper insights. As a result, fixing bugs takes longer each time, and you have difficulties keeping the system up and running. Users may start complaining about awkward performances or crashes.
In the end, you do not see any other solution than moving into a modern cloud computing environment to use additional resources quickly. But wait, then you realize your application grew already into a too big and complex piece of code carnage that requires a complete rewrite, so you have to spend many months, a considerable amount of money, and maybe even lose significant parts of your customers in the meantime, for doing what you should have done from the start to avoid this sad story: caring about your software architecture.
What is Software Architecture?
From a high point of view, the software architecture is a high-level abstraction of a software system. It describes what the system does and how it works but it also gives you insights into how well the software system does its job. Concretely, software architecture addresses the two major concerns when building a software system. Firstly, the system’s functional requirements. They are considered by describing the software components that form the system’s structure and how they behave and interact by defining data and workflows. Secondly, software architecture needs to address, within given hardware & technology constraints, all non-functional requirements to ensure the system works well and within specified quality parameters. Let us explain those terms in more detail.
Functional Requirements
The functional requirements represent the business logic, the functionality and features the software provides. They specify exactly what a software application or system is supposed to be doing.
Software Components
The software components are the individual functional building blocks, the individual units or modules that together build up a software system. Each component is responsible for a specific piece of the overall functionality. This can be a service, a message queue, or any kind of storage backend, e.g., a database. However, depending on the chosen architecture (various software architectures will be discussed later in this article), this can also be a layer or module within a single large, self-contained service.
Software components are coherent building blocks of the system that can be individually managed, tested, and ideally also deployed.
Data- and Workflow
Software components can communicate with each other either synchronously over direct interfaces or asynchronously, by actively requesting for messages or by getting messages passively as soon as they are available, e.g., via message brokers, event notifications or even by sharing state information through a database. All those communication methods have in common, that they aim at transferring required data or work instructions from one component to another. Data and workflow describe how and what is communicated.
The general objective is that components collaborate to fulfill a larger function while the type of communication is specific to the problem to solve and its non-functional requirements. May the communication be in-real time or delayed, the data and workflow between components ensures the correctness, integrity, and reliability of the larger function. With distinct types of communication, you can achieve different solutions to avoid bottlenecks and increase scalability and throughput.
Non-functional Requirements
A key aspect of software architecture is to meet the non-functional requirements of a system. Non-functional requirements are quality and performance attributes that a software system must meet. They typically address execution times, the reliability or security of the system. Non-functional requirements are essential to determine whether a system works well in all use cases.
Examples of non-functional requirements are:
- Performance to ensure the system can handle a given load, e.g., in terms of throughput or single response times
- Scalability to ensure the system can easily be adjusted to a varying load
- Availability to ensure the system is always up and running within given boundaries
- Reliability to ensure that the system is functioning correctly within certain guarantees, handles errors gracefully, etc.
- Security to ensure safety and integrity of data and system
Hardware and Technology Constraints
Another aspect of software architecture design that should not be underestimated is based on the hardware and technology constraints imposed on the software system.
The hardware constraints need to be addressed when considering non-functional requirements. It must be ensured that available or planned infrastructure is sufficient, and no cost explosion is caused when additional hardware must be purchased. A key aspect is to ensure that software components can efficiently work with available hardware resources, e.g., CPU quantity, memory size, storage type and capacity, and networking overhead and speed.
The technology constraints are related to software dependencies. Potentially, certain frameworks, applications or technology stacks must be used or are not allowed in your application. For instance, the data that your software is going to deal with is stored in a specific relational database or license fees have to be avoided which may rule out a specific technology stack or, on the contrary, due to a partnership with a software provider, a specific library, communication protocol or web framework has to be used.
Such hardware and technology constraints contribute some extra complexity to your software architecture but are inevitable when it comes to the best design.
Learn more about typical software architecture patterns in part two of this blog post series. Coming soon.
Author © 2024: Dr. Tom Crecelius – www.linkedin.com/in/tom-crecelius-65a16949/