Why software ends up complex
Complexity in software, whether it’s a programming languages, an API, or a user interface, is generally regarded as a vice. And yet complexity is exceptionally common, even though no one ever sets out to build something complex. For people interested in building easy to use software, understanding the causes of complexity is critical. Fortunately, I believe there is a straightforward explanation.
The most natural implementation of any feature request is additive, attempting to leave all other elements of the design in place and simply inserting one new component: a new button in a UI or a new parameter to a function. As this process is repeated, the simplicity of a system is lost and complexity takes its place. This pattern is often particularly obvious in enterprise software, where it’s clear that each new feature was written for one particularly large customer, adding complexity for all the others.
Every feature request has a constituency – some group who wants it implemented, because they benefit from it. Simplicity does not have a constituency in the same way, it’s what economists call a non-excludable good – everyone benefits from it. This means that supporters can always point to concrete benefits to their specific use cases, while detractors claim far more abstract drawbacks. The result is that objectors to any given feature addition tend to be smaller in number and more easily ignored. Leading to constant addition of features, and subtraction of simplicity.
Escaping this vicious cycle is not easy. One can easily say, “so reject all feature requests”, but a project that does so will eventually find itself unable to serve its users' needs at all! Our approach must be more measured: we need to spend as much time thinking about how a new feature will burden all of our users, as we spend thinking about how it will benefit some of our users. We should also spend time thinking about how to design new features in a way that maintains what Fred Brooks' called the “conceptual integrity” of a system, rather than by merely tacking something new on.