In software products there is no architecture which “the” right architecture from all aspects and there is no architecture which is wrong from all aspects. Generally a software product or application can be developed in various ways and will have many plausible and viable architectures that can be considered and implemented. It is the decision of the architects to choose one of the various architectures and use it to realize the product. The decision could be made due to different reasons. The architecture decision taken at a point of time has an impact which could be far reaching and not changeable. One needs to be aware of the impacts of the decisions and need to identify which among them will be difficult to change in future.
Which software architecture decisions are difficult to change ?
I will discuss a few of the software architecture decisions that are crucial but by no means this is all that matters.
The Technology stack
The technology stack that is used to develop the product can not be easily changed. Today is the era of off-the-shelf products or libraries which are developed in different technologies. The task often for the architects is to choose these products, evaluate them and stitch them together with some custom code and only focus on the implementation of the business logic. Once we find a combination that works it is difficult to change one off-the-shelf product or library that is built upon one technology to another because a new and better technology is available. Each technology has its own advantages and limitations. Sometimes , the functionalities are given depending on these functionalities and limitations. Custom code is written around these functionalities and limitations. That is why it is very important to design the architecture where changing technology or library or the off-the-shelf product can be possible with as little effort as possible. The chosen technology stack should not be very old and should show to be stable and promising in the next few years.
Create from scratch vs Reuse existing
Sometimes there is a dilemma whether we create the building blocks of the product from scratch which takes a lot of time and may not beat the performance and usability of an already available off-the-shelf product that just does the same or more. Sometimes we tend to use old code or functionality to minimize cost and effort. Both decisions have their own drawbacks. When developing something from scratch it also has to be maintained and new features need to be introduced to meet the demanding market. At times this can be challenging. When we try to reuse the technology, software or service can not withstand the constant change of technology and may get obsolete soon compared to a new de facto standard.
When it comes to low level functionality, the development languages differ from each other. Also, the new technologies and reusable libraries built using one development language could outperform another language. For example many AI and machine learning libraries are developed in python because of the ease of use of the language. It will be difficult to rewrite the product in another language later because the development language used does not offer the new libraries based on which new features can be developed.
Open source library
When there are open source libraries used, the license of the library is the most important aspect to understand. Along with that it also should be noted who is the owner of the library. When the owner is an individual then it is unlikely that it will be maintained and enhanced over a long period of time. Also in this case the trustworthiness and stability is questionable. When the owner is an organization then it might be more trustworthy and stable but a new organization also could not exist longer. Important to understand who is supporting the organizations, are there companies who are contributing or there is only a single company behind the organization. When there is only a single organization it might not be able to maintain and update the features for a long time without any revenue. We also should look at whether the open source library has a thriving community or developers and users. This aspect also ensures that the library will be functional for a long period of time and help could be available from the community.
Though all relational databases almost provide the same features but not always exactly the same. There could be some feature that eases implementing data processing and handling and storing in some way which other databases do not offer. Specialy the differences here are in the in-built functions each database offers. Also different relational databases work fundamentally differently, like HANA databases can work both as row store and column store. When the individual feature of a database is used extensively it will be difficult to change the database later irrespective of the fact that the database layer is different from the business logic layer. Also, the performance of the database could force us to change it later. One database might handle less data load fairly well but may not be able to handle a large or huge data load reasonably. Again, the decision whether a relational database or a non-relational database like a semi structured database or only a key-value pair database will be used will be difficult to change later as the implementation of logic in the programming language can become too dependent on the type of the database used.
Revenue model to follow
The chosen revenue model has a direct impact on the architecture because it has a direct impact on how the product will look and how it will work fundamentally. For example, when the revenue model will be to directly take money from its users though a subscription payment, yearly or one time or by customers buying a license the software also should be designed to be more resilient, fault tolerant, less buggy and more performant. These aspects need to be incorporated into the architecture and ensured. On the other hand if the software is free to use few of the quality aspects like resilience, fault tolerance and performance may not have to be very high. When the software is free for use the revenue might come from third party advertisements. In this case this aspect of the product or application has to be part of the design so that acquiring and displaying ads are possible. Even more when we would like to display ads based on customers interest or past activity such features should be added right in the architecture itself. Similarly, how the product will be built has a direct impact on how the revenue can be generated from the product. For example, when a product is built to work on-premise the revenue has to be based on lease or license keys. The same product when built to work on cloud could be based on metering the actual usage of the product by the customer.
There are many such decisions that could be an important factor in the architecture decision. A potential drawback down the line always may not be very obvious to detect early or right in the beginning. When they are detected early, they have to be written and a potential mitigation plan has to be attached. Also the reason why each of these decisions are made needs to be written down. This helps the new people in the project who are in charge of managing the product or architecture at a later point of time to find some rationale behind the decision. The boundary conditions that played a role while making these decisions also needs to be clearly mentioned. The decision why some other viable architecture was not chosen also needs to be documented. These reasons often point out some drawbacks or technology limitations. When they are written clearly later someone else managing the project and product will not have to guess. The decisions can be changed to consider a discarded architecture again later because of change in boundary conditions or change in technology limitations. When change in the architecture can be implemented with less or reasonable effort these documents will help the new architects to make new decisions.
Be aware of your technical debt
There could be technical debt incurred by an architecture. When they are ignored or incurred in the beginning and not paid attention they increase later and need to be addressed. For example, during working on a Proof of Concept (POC) one might take one or several shortcuts that compromises performance or quality or is a hacky code in general. These debts need to be tracked:
When the debt was created?
What was the reason for it?
What problems might it cause in the future?
How to solve those debts and when?
A debt can happen during the design phase, during PoC, or when an issue is identified. The debt might be created because of lack of time to implement it in a good way, lack of technical knowledge or budget or political decisions taken by managers. The risk of not resolving it is that the history behind the debt might be forgotten and the debt makers could leave the company or project. So, the knowledge might be lost. It may lead to a redesign of a certain part or the whole architecture. Maintenance cost may increase and effort may be wasted to troubleshoot and solve the incidents. This is why it is wise to note down all of the debts.