ChatGPT refers to the software architecture (SA) as the fundamental structure and organization of a software system. It is how the software components interact with each other and with the hardware, as well as how data is processed, stored and communicated. Software architecture provides a conceptual framework that helps understand how a software system is built, expanded, and maintained over time. From this point, I want to share my opinion as a software engineer about the importance of software architecture, which plays an important role as it provides a solid structure that allows us to understand and manage software development. Throughout this article, I will present some examples making analogies with the architecture of constructions in the physical world, providing a direct and clear way to understand it, always from my own perspective and experience as a developer.
SA is important because it defines the structure needed to start the development, and provides global guidelines that help create reliable and sustainable software. Is this enough to determine if it is important for software development? Not for me, so I have identified three approaches that could help me explain the importance:
Measure twice, cut once.
Using sledgehammers to crack nuts.
Uncoordinated efforts, chaos ensured.
Imagine you need to build a dwelling for your clients and you have a solid knowledge of construction. With this background, there are no obstacles to starting construction right away. You decide to get to work and start making preparations. You buy the necessary materials and begin the construction process. After a few days, you've managed to build four walls and a roof. The first phase of your house is complete. After completing this initial phase, the clients verified the work but received a surprise because they were expecting a skyscraper. Now you have a big problem since you've invested time and effort in building a house instead of the skyscraper they want. This leads to an extra effort to rebuild what you've done in the first phase or make adjustments to reinforce the structure and meet one of the main criteria. This results in additional costs and extra time.
This situation also occurs in software development. Imagine that you need to create an application for a new client, you decide to implement the same set of guidelines that you have used in the last project you have worked on, without analyzing the context and objectives for the new implementation. After developing the first delivery, you discover that the chosen guidelines do not fit or generate conflicts with the expected solution, so you have as a result an application that is not scalable, maintainable or that cannot be adapted to the required needs, now you have to invest time and effort in refactoring the code to adapt it to what is really needed.
Let's continue with another example. Imagine we're going to build a skyscraper, and it's planned with a structure resistant to earthquakes. This involves using special materials and a specific construction method. However, the area where the building will be located is not earthquake-prone. The architecture of the construction is being designed to solve a problem that doesn't exist in the geographical area. In many cases this often happens in the software world , where the approaches attempt to cover non-existent situations (or situations that will rarely occur) or where very complex architectures are designed to address very simple developments, either because they are trying to sell an expensive solution or because they are following an unnecessary technological trend, the point is that they are not taking into account what the software needs. It would be like designing an architecture based on micro frontends and microservices that could be useful if the project expands at some point, but the user only needs a view (which could be static) to see their contact information.
Therefore, defining a good architecture is important, as it allows establishing foundations that are aligned with the software’s needs, preventing approaches that try to cover more than what’s necessary, but it is important to keep in mind, that the software has to be flexible, to be able to scale or improve in the future if necessary. We can reinforce this idea with a quote from the book "Clean Architecture" - "If you can develop the high-level policy without committing to the details that surround it, you can delay and defer decisions about those details for a long time. And the longer you wait to make those decisions, the more information you have with which to make them properly."
In construction, the work is done in shifts, which are divided into morning and afternoon schedules. There are different teams working on the same elements and tasks, continuing the work left pending by the other team and vice versa, with the goal of completing the project together. What is the problem if we don’t define clear guidelines? No one knows what rules to follow, so each team uses a different “bill of materials, architectural design or rollout plan”. One team uses oil-based paints, another uses water-based paints, some use brushes, others use air pressure machines, and so on. The project continues because each team is making their contributions, but when you look at the work as a whole, it can be a complete disaster, since each one has been using the elements that seemed best to them, without any general guideline.
This also happens in the software development world when developing an application with multiple teams, each with different responsibilities. You might think that a bit of organization could solve this situation, and yes, in some cases that can be the key, but this is again where a clear architectural framework can help, providing guidelines and a clear way to collaborate, allowing software integration to be simpler, easier to maintain and to understand, as a result all teams can work independently and at the same time be aligned. A famous example was the Mars climate orbiter incident where a difference between the output of one part of the software and the input of another could generate a dab result, even when both parts were working under the same framework.
The above examples provide us with a simple view of the vital importance of software architecture. It should be noted that the analogies presented here cannot be interpreted as a manual of procedures, but as a tool with the purpose of representing some situations to enrich our understanding, rather than defining specific workflows.
It is crucial to understand that software design should be a progressive process. In the initial phase, the main task is to define only the essentials, defining the basis for a solid development. This approach leaves room for adaptation, which is able to evolve with the software conditions, being like a roadmap that guides the constant evolution. Here are tips that can help software developers define a good architecture:
Acquiring knowledge about design patterns should be one of the first tasks to start understanding this field. Refactoring.guru is a website with good information on this topic, allowing you to gradually grasp the various existing patterns, presenting a problem and its potential solution.
Analyze and outline before executing. It's always a good idea to take the time to analyze the situation and characteristics of the project you're working on, long before you start executing, as it will give you a clear idea of what's needed.
Keep in mind three fundamental principles for software/architecture creation: DRY (Don’t Repeat Yourself) - KISS (Keep it Simple, Stupid) - YAGNI (You Aren't Gonna Need It). Keeping the software simple, avoiding repetition, and implementing what's necessary makes these principles fundamental when designing architecture.
Define a good design (the basics) only with the essentials, this is an iterative work, as recommended by Ron Jeffries and remember, you don’t need to define anything you don’t need.
These are some important tips that are always good to keep in mind when working with software architecture. We could conclude with a quote from the book "Clean Architecture" that says, "Good architecture makes the system easy to understand, easy to develop, easy to maintain, and easy to deploy. The ultimate goal is to minimize the lifetime cost of the system and to maximize programmer productivity."