Deciding about software architecture has to include a lot of elements. There is no one universal path that every product should apply. Architectural drivers are highly context-dependent, and they all are linked, so we need to remember that tweaking one of them often will link to a shortfall of another. Usually, you can distinguish functional and non-functional requirements. The former basically describes what should be done, the latter how. For example, creating an e-commerce application with online payments can be perceived as a functional one. Ensuring that it can support up to 10k purchases per second belongs to non-functional requirements.
There are four groups of architectural drivers:
- technical constraints
- business constraints
- functional requirements
- quality attributes
Software constraints declare the boundaries for the project, and they need to be applied under all circumstances.
Those are usually set by the development team and are difficult to reverse. For example, you can have a programming language, framework, legacy systems and dedicated platforms. To a large extent the team can choose a constraint together with stakeholders to have an impact on the work environment.
Business constraints The most common elements of the business part are:
- timing (there are always periods dedicated to particular stages of the project)
- budget (amount set in the contract, which is often the place where compromises need to be made)
- team (number of team members should be fixed at the beginning of the work).
It is easy to make the product do what it intends. But shouldn’t we instead focus on supporting the stakeholders’ expectations? Functional requirements define what we need to run the process. But as it’s not the only thing that matters (what about security? or convenience?), we need to keep in mind that we need to have to keep in mind various perspectives. Also, the value of maintenance is an essential factor here as it’s what can highly contribute to lifetime cost.
Also called ‘’ilities’’ after the suffix they share ;) Characteristics such as scalability, availability, testability etc., need to be prioritised based on your project needs. For example, availability is the ratio of time when your system is working, which can be crucial in banking. If you wonder about the security of your application, here is where you should consider prioritising blocking unauthorised attempts that can provide access to your users’ data.
An example of the trade-off
Web browsers have many security mechanisms that prevent attacks in order to make the services unavailable. Some banking websites have decided to create an extra pop-up window (sandbox environment) for the transaction to avoid it. Looking at security (as one of the quality attributes) is a great decision that leads to raising the level of security on the web. On the other hand, opening an extra window is a poor solution for user experience and usability.
How to document design decisions?
Whenever we make an important decision that will affect the architecture, we should leave a trace of it. Thanks to this, we will be able to make conclusions from past decisions and understand the circumstances in which they were made. A document that contains this information is called Architecture Decision Record (ADR). There are many templates to use when creating this document, but they need to include title, context, alternatives, decision, and consequences. Each decision is stored in a separate ADR file. Recording the work this way helps in many situations like changing teams where future team members will understand why particular choices were made. It will solve the problem of losing context and decreasing productivity.
A decision can turn out to be right only in the context
That decisions documentation can sound redundant at first, but it’s a crucial thing, which can save a lot of effort during further product development. A common misbelief is that there is one right and sacred way of creating good architecture. It’s especially visible while passing the codebase from one vendor to another. If you have ever needed to have your car repaired, you know what I mean - “Oooo, I see that many parts need to be replaced, your previous mechanic did a really poor job!”. It’s easy to judge past decisions with the benefit of hindsight. But definitely, it’s not just and not that useful. No one wants to hear that everything needs to be replaced, and the final cost is the equivalent of a new car.
I hope this article about architectural drivers explained why deciding about them is such a complex and vital task to do when creating an app. There is no unique solution that you can apply to your project as there are so many variables available, and they are all linked in particular ways. Making the right decisions at the beginning of the process increases the chance of success. Sometimes it’s even “to be or not to be” situation. Remember to discuss with the team and stakeholders - this decision should include all perspectives. Balancing drivers is specially important during post-MVP phase. There are many other common challenges which you will face during this period. You can read about them here.