I was just discussing software architecture and next steps with a team building a tool to help analyse MRI images of brains. Most of the questions we asked explored ways to proceed by focussing on change:
- what if the budget for that commercial component shows up? How would that change the system?
- what if you find this data source isn’t good enough? How would you find that out?
- which of these capabilities does the customer find most important? When will they change their minds?
that sort of thing.
We have all sorts of words for planning for, and mitigating the risk of, changes in low-level software design. In fact a book on building maintainable software talks about nothing else, because maintainable software is antifragile software.
But it happened that I wasn’t reading that book at the time, I was reading about high-level design and software architecture. The guide I was reading talked a lot about capturing the requirements and constraints in your software architecture, and this is all important stuff. If someone’s paying for your thing, you need to ensure it can do the things they’re paying for it to do. After all, they’re probably paying to be able to do the things that your software lets them do; they aren’t paying to have some software. Software isn’t real.
However, most of the reason your development will slow down once you’ve got that first version out of the door is that the world (which might be real) changes in ways that it’s hard to adapt your software to. Most of the reason you’re not adding new features is that you’re fixing bugs, i.e. changing the behaviour of the software from one that matches the flawed conception you had of what it should do to one that matches the flawed conception you now have of what it should do.
A good architecture should identify, localise, and separate sources of change in the software system. And then it should probably do whatever you think the customers think they want.