These are the slides with some notes from my talk about software architecture when developing in an agile way. Contents
Even if you invested a lot of time upfront to get all the requirements and to make wise technology decisions, requirements and technologies will change.
Requirements change because the stakeholders see new possibilities or there were misunderstandings.
Technologies change all the time and at some point, you have to keep up or the product will die.
How can we design a software architecture so that it can cope with these changes?
The architecture should be flexible – it should support change. One essential aspect is to build the system out of exchangeable parts. Parts that can be replaced to better suit new requirements or to get rid of old technologies.
One important aspect in designing these exchangeable parts is the separation of concerns. When we change one part, the other parts should not be affected. Otherwise, local changes are impossible.
Another important aspect is that the way we model reality in software should reflect the user’s mental model – the way the user thinks that the software is operating.
If our stakeholders think in terms like seats, tables and beds, we probably should use a model that knows about these individual types and not use a model that only knows furniture. If we only use a model composed of furniture, we probably cannot easily follow changing requirements regarding beds only.
Ultimately, we want to achieve a software architecture that is evolvable. A software architecture that can handle all of today’s needs – and nothing more – and that is open for future needs through flexibility. An architecture that is not over-engineered but somehow still anticipates future changes.
It is impossible to achieve this completely, but we can at least use the goal of perfect evolution as a thinking tool to make architectural decisions.
If we take a look at Max’s job to build software to match employees based on their skills to form a team for a certain task, we see that there are two main evolutionary steps. First, an in-house solution for only a few users with little requirements regarding performance. Second, a SaaS that should cope with 10’000s of users.
These two evolutionary steps can be broken down into a sequence of smaller steps. Max and his team could first build a very simple command-line application that needs two JSON files as input – employee data and team data. Then the team builds a first version of the algorithm. If they succeed, the keep going. If they fail, then at least they didn’t invest a lot of time into a fancy UI. Once the business problem is solved – the software can match employees into a team, Max and his team can continue by making the software more accessible by adding a nice UI, keep the data in a database and add some validation to prevent wrong inputs. Then they can improve the algorithm Now, the team achieved the first version of the product.
Then they continue to add security so that the software can be used outside of the intranet, add multi-tenancy to simplify deployment for multiple customers and address scaling issues when the number of users is growing. Finally, the team can optimise for low infrastructure costs.
This is one possible path of evolution. The team can think of other paths and discuss differences and their consequences. Maybe the most important thing is the UI, so it should be built earlier. Maybe there are several options for scaling like Kubernetes or serverless.
Of course, these paths change on the way. Whenever the team acquires new knowledge, the possible paths should be updated.
Continue reading: No time for improvements