A good Software Architecture
adan condori
Tech Lead | Engineer Software | Ruby on Rails | IOS Developer | Android Developer | Flutter Developer | Scrum Master | Power BI | Management AWS Azure | Patterns Desing | SQLMySql, Postgres | Architectura Patterns
Summary
Nowadays software products are very varied and therefore a variety of software architectures are used. Which demonstrates the success of a software project and the acceptance as a good architecture, therefore in this essay we will be talking about the benefits, practices, recommendations and fundamental concepts to create a good software architecture. I should mention that we will not talk about technologies because of its constant change in our profession.
Context
So, let's start by talking about what is a Software Architecture, there is no correct definition of what a Software Architecture is. However there are several definitions that have the same concept, for example "A Software Architecture represents the structure or system structure, consisting of software components, their external visible properties and the relationship between them", based on the above definition we can comment and infer that the software architecture is not only limited to define the components and their relationships, but to be clear about the relationships between objects, and the identification of appropriate technologies to build the system, on the other hand it′s important to understand the non-functional requirements of the system, document and communicate to the stakeholders.
Body
The Software Architecture serves as a blueprint vision for the software development team, who will be implementing the business requirements, to have a better idea. Software architecture is not a static blueprint but rather an evolving process of strategies, techniques, design patterns, architectural designs and components. By building a good architecture we can identify design risks and mitigate them in advance.
One thing I have learned over the years of experience in software development is that not even the customer will know what he wants. Therefore it′s important to have some document for all the functional and non-functional requirements, plus a series of interviews with all the people involved in the software, all this with the aim of understanding the business. In this way we will be able to define a base architecture according to the client's needs, and we will also be able to define the technologies that fit the system.
In the following we will answer the coming questions:
Which criteria do you use to define such architecture as good?
There are many systems quality criterias that we can discuss, but for me, the following architecture characteristics are a solid basis for obtaining a good software architecture.
- Understandability.- It means that our architecture is easy to understand by the development team and stakeholders, at the same time it should encompass all business requirements.
- Usability and Learnability.- This point is related to UX/UI requirements which is important when defining the technology in which the software will be developed. Architects must be conscious when defining technology and architecture.
- Security.- This is an important factor for the software, it consists of restricting the access of the users or components based on the authentication. This way it will be able to protect from DDoS attacks, SQL injection and alert the system.
- Reliability and Availability.- It is very important in the design of the software architecture, because reliability is an attribute of the system responsible for the ability to continue working in predefined conditions and Availability represents that the system will be running 99.9%, otherwise you must have contingency measures such as emails or notifications.
- Interoperability.- Most application services must communicate with external systems to provide complete services. A well-designed software architecture facilitates the interoperability of the application to communicate and exchange data with external systems or legacy systems.
- Testability.- The foundation of a good software architecture is based on ensuring that the design of each component is testable. A testable architecture must clearly show all interfaces, and the integration between components. All functional and non-functional business requirements (NFR) must be consistent and fully testable. Ensure that all DEV, TEST, UAT and PRODUCTION environments are similar.
- Scalability.- The defined technology architecture must be able to scale without affecting performance. There are two types of scaling: vertical scaling and horizontal scaling. Vertical scaling consists of adding more CPU/memory/disk hardware to the existing server. Horizontal scaling consists of splitting the load and responding to requests by adding more servers/instances to the server cluster. Horizontal scaling is recommended.
- Agility/Performance.- To bring agility to the architecture we must follow the direction of "informed anticipation", the architecture should not anticipate and design the application, which will delay the delivery of the application and add more complexity to the developer. At the same time, it should not under-anticipate future application demands, which will pose a risk to feature development in the absence of architecture guidance. Architecture agility requires "just right" anticipation. To achieve this "fair" architecture anticipation it is necessary to be "informed" there are several methods to be informed such as dependency analysis, product backlog and technical debt.
- Observability.- Applications and services are developed using different architecture styles such as microservices, serverless and event-driven. Monitoring has become the key to maintain the health of these services. Observability is not just a fancy new term for monitoring. Observability adds much more along with actionable information along with monitoring, such as log aggregation/analysis and notifications.
- Fault Tolerance.- When designing applications or services that are going to communicate different systems in different infrastructures and tend to fail partially or totally due to Network Latency, connection breakage, or any other reason. In case of these failures, the Architect must design where the Application or Services should continue to operate, possibly at a reduced level in case of failure. There are two types of tactics that can be adopted at design time and at run time. During design time, we can expect what return values are expected from each operation and ensure that there are no buffer overflows. At runtime, we must adopt what second action to take in case of failure to ensure that the system continues to function.
- Which benefits does the architecture provide over the inhabitants of the system?
The benefits of a good architecture are:
- Create a solid blueprint or basis for the software project.
- Scalability of the software project.
- Reduce maintenance costs.
- Increases the performance of the software project.
- Better maintainability in the code.
- Allows quick changes in the project.
- Helps in risk management. Helps to reduce risks and the possibility of failures.
- Greater adaptability to new requirements, since the software architecture creates a clear separation of concerns.
- Better communication with stakeholders.
- Auditable and testable.
- Which trade-offs have been made in the system to keep the architecture?
In Architectural Design there are important decision making considerations:
- Flexibility vs simplicity
- Space vs Time
- Latency vs performance
- Safety, Stability, Maintainability, Security
- Which recommendations for improvements you have over the architecture?
For the design of a good architecture it is important to have a multi-disciplinary team and some of its members must have several years of experience in software development, then I will list some recommendations that I use and investigate when I have developed software.
- Analyze and verify if there are dependencies with external components, API, external. If they exist, the communication protocol must be defined.
- Have close communication with the client to know the process and the requirements of the solution.
- Define which architecture patterns are going to be used.
- Define which components are going to be used or created.
- I Recommend that the team be aware of some concepts such as SOLID, KISS, DRY and YAGNI, these concepts will help the team to make a maintainable code.
- Know and apply design patterns, refactoring, which will help us to have a clean code.
Conclusion
In this article I have presented my research and ideas on what the characteristics of a good software architecture should be. Each of these characteristics deserves a longer discussion and there are also other characteristics that are not touched upon.
The software architecture you design should always be focused on what the customer needs, on understanding what our software is going to do and how it is going to do it. Being able to know the pros and cons of each option we take before we start coding.