Simple, reliable, fast (in that order)📄 BetterWays.dev wiki page | 🕑 Last updated: Sep 15, 2022
If I had to summarize my approach to software development in three words, the words "simple, reliable, fast" come to mind.
This phrase is my variation of Drew DeValut's "Simple, correct, fast: in that order" phrase. While "correct" is definitely a relevant word here, I think "robust" and "reliable" are more relevant.
So, let's try to first define the words "correctness", "robustness" and "reliability".
I'll use Matthew Wilson's definitions (from his "Quality Matters: Correctness, Robustness and Reliability" article), because I think they make the most sense in this context:
- Correctness: The degree to which a software entity's behavior matches its specification.
- Robustness: The adjudged ability of a software entity to behave according to the expectations of its stakeholders.
- Reliability: The degree to which a software system behaves robustly over time.
While all three words are relevant in this context, in the practical sense robustness is more relevant than correctness, and reliability implies robustness over time.
The question is - how do we achieve these characteristics, and more importantly, how do we maintain them in the long term? Obviously, these characteristics are important for all software projects, but the vast majority of them end up having almost the opposite characteristics.
So, why do so many software projects fail in that regard? Complexity has a lot to do with it.
Complexity kills, and it's extremely easy to introduce additional complexity on every step of the way.
"Simplicity is a great virtue but it requires hard work to achieve it and education to appreciate it. And to make matters worse: complexity sells better." (Edsger W. Dijkstra)
Simplicity-first approach definitely requires a lot of hard work, but it's almost a prerequisite for these characteristics:
- robustness and reliability ("Simplicity is prerequisite for reliability" - Dijkstra)
- performance (simple code is much easier to profile and optimize)
- composability (try to make your design composable - when you have a complex problem, try to split it into smaller, simpler composable parts)
On the other hand, with more complex/intertwined solutions, even if you manage to temporary achieve those characteristics, it will be extremely hard (or impossible) to maintain them in the long term.