When we develop a piece of software or functionality the following is true in many cases: It does not need to be super performant, it does not need to be robust to handle every imaginable error or flexible and generic to meet any future need. The test coverage does not need to be 100% and the code does not need to be perfect.
Nevertheless, as developers we are often tempted to do things that probably nobody needs, like adding “super cool features”, refactor code just for the sake of perfection or optimize performance without any need. Or we build a super generic framework for something where flexibility isn’t a requirement. We use the most powerful libraries available, build sophisticated class hierarchies and optimize our algorithms to be even more memory efficient and faster.
Don’t try to make it better then required (do the right thing)
We do this with the intention to build something great (ok, maybe sometimes we only do it because it’s fun or just to show “we can”). But what we often don’t consider is that when adding things that are not definitely required, it might cause a huge amount of waste - instead of making something better the opposite is true:
- We invest time (and money) for something potentially useless.
- We add unnecessarily extra complexity (=accidential complexity) what causes waste during the whole lifetime of the software.
=> We should avoid adding extra functionality, flexibility and other optimizations if there is no definite purpose. Even achieving 100% test coverage and trying to make the code perfect does more harm than good if we do it just for the sake of idealism.
To answer the questions about what’s necessary and what’s not is difficult. The answer depends on many factors like our knowledge, our experiences, customer requirements, our visions and much more - there are no simple rules because software development is complex. But what we should regularly do is to ask ourself the following questions:
Why do I do this? What’s the value? Is it really necessary? If this questions cannot be clearly answered in favor to what we do, we are probably wasting time, effort and money.
We also shouldn’t guess what might be required in the future, instead we should make our decisions and planning guided by facts and experience. We should be aware of the reason for what we do. We should strive to “do the right thing”, keep it simple and concentrate on what’s important now.
Keep the quality high (do it right)
As long as we don’t just write a quick prototype or a “throw away” script, high quality should always be a requirement. We know that low quality source code can be another huge source of costs and frustration, especially for a growing, changing and/or aging codebase. Where premature optimization, gold plating and overengineering is too much of a good thing, we also should be aware of the consequences of technical dept and try to “do it right”.
Conclusion: Good enough is just right
It’s counterproductive trying to make software better than it needs to be - we should concentrate on what’s really needed. The quality should be kept high. Too much of a good thing as well as too less (e.g. low quality) yields waste an introduces accidential complexity.