Programming principle "YAGNI": you ain't gonna need it
The programming principle YAGNI (You aren’t gonna need it) originates from extreme programming, which is an agile software development methodology that advocates frequent releases with short development cycles.
"Always implement things when you actually need them,
never when you just foresee that you need them."
Foreseeing the future is a tough nut to crack, that is the main rationale behind YAGNI. Every time we do work that might eventually pay off in the future, chances are high that we are mistaken and are simply wasting time and energy. Moreover, developing, testing and maintaining a new feature is expensive and should only be done if deemed absolutely necessary.
Why is following YAGNI often so hard?
The ability to look into the future is not commonly available to us human beings. But why is it still so hard to follow YAGNI? Let’s look at two common examples.
Taking a peek on the back-log
Let’s assume we are working on a feature that adds a new column
A to a database. Coincidentally, we already know that on the back-log there is another feature that will also require the addition of another column
B. Doesn’t it make perfect sense to add both columns in one go? After all, we are now already familiar with all the places that need to be modified for that extension. Why waste that knowledge and do the same thing once more in four weeks time?
The back-log is not set in stone, but rather a living thing. The feature requiring the addition of column
B might get postponed or dropped altogether. In the meantime, our addition of column
B (and all the other necessary modifications) is likely to confuse the other developers working on the code base. They might be thinking: “Why is
B here? I cannot see where it is used. Is it an old artifact that should be deleted?”. After all, we spend more time reading code than writing it. Additions that are not used yet are wasted time when people try to make sense of them. In addition any refactorings that also touch the new column
B extensions will be more effort, even though column
B isn’t even used at all.
Overengineering things to accommodate future changes
Planning too far into the future sometimes makes problems harder than they actually are. Also, coming up with a perfect design from the start is a very hard thing to do. Luckily, software development is not like architecture. When building a bridge, one needs to plan everything perfectly right from the start. With software, things can change, grow and improve over time.
From our experience, the best solutions come up naturally with a code base that is easy to change and refactor. This way it is easy to employ future learnings or add additional functionality. Typical practices that lead to an easily changeable code base are:
- A high coverage of automated test to be able to do safe refactorings.
- Following the single responsibility principle, i.e. a function or type should do only one thing at a time.
- Follow the DRY principle, which you can checkout in one of our previous posts.
How to embrace YAGNI
In the heat of a fluent coding session, it is not always easy to resist the temptation to build more than is actually required at the current point in time. Here are two easy rules that you can follow to avoid breaking YAGNI.
Outrule commented out code
Commented out code might seem like a good idea to not forget things that we have researched and tried out to implement a feature that is not needed yet. After all, we might need it in the future. But as the surrounding code changes, our commented out code might stop working. Also, such commented out code will make most developers stop and read it to figure out why it’s there. We developers are somewhat curious people after all 🤓. So the commented out code that was committed with good intentions is - almost every time - just cluttering the code base without any benefits.
We recommend installing a linter that prohibits commented out code from being merged in the first place. This way you avoid any discussions on that matter.
Submit minimal merge requests
Small merge requests have several benefits:
- They are merged faster, which reduces the likelihood of stale feature branches.
- They lead to fewer merge conflicts, which reduces the workload during the final polishing steps of the feature branch.
- Other developers working on the same code base will benefit sooner from your additions.
- Every actually integrated change helps users of your products.
As a consequence, small merge requests lead automatically to a YAGNI approach as you are not tempted to add things that are not required for the feature you are currently working on.
Foreseeing the future is an impossible task. We still very often think we know what is needed next in our project. As long as you have not pulled an issue that actually requires you to do a certain extension, resist doing it just yet. You will produce more work than you think you are currently saving.
Make sure to get notified of any new blog posts regarding coding, testing, features of Symflower or developer memes, subscribe to our newsletter. You can also follow us on social media and - if this post helped you - please share it via Twitter, LinkedIn or Facebook.