You’ve probably heard of the YAGNI principle, it stands for (You Ain’t Gonna Need It). Essentially it is meant as a mantra for developers to prevent us from anticipating functionality and building things before we know that they are actually necessary. You can think of it as an Agile principle or an unspoken (or sometimes vociferously spoken :)) rule if you like. Regardless, it can sometimes be a good idea to keep this principle in mind and measure much of what you do as a developer against it to make sure you’re not building a ‘mountain’ when a ‘mole hill’ will do just fine.
I like the idea of YAGNI and often try to apply it to what I do, but just like any principle that has been around for a while I have seen the message (or the idea behind the principle) be diluted to the point where some people start to use it without thinking and without understanding what it is all about.
Applying YAGNI Without Thinking
You know you’re applying YAGNI without thinking when it becomes the first and only yardstick for anything you do as a software developer. Implement a pattern? No way – YAGNI, a simple loop will do. Use a utility library? What for – YAGNI, it’s just one simple method, we can roll our own. How about building in more automation around our deployment process? Bah – YAGNI, we only do this once every 3 months, we can do without.
Don’t get me wrong I am not advocating always using patterns, or libraries, or automating without thought. What I am trying to say is, you can’t unilaterally apply YAGNI to everything without considering the larger context. If I do use a pattern here, will it make my code more readable, maintainable, testable, if the answer is yes then perhaps the pattern is a good idea. The point is, YAGNI in and of itself is not an objective it is just a practice, a tool. No matter what task you do you should always be aiming to make the system easier to understand and easier to use, more testable and maintainable, cleaner and more robust. If that means writing a little bit more code and putting in a little bit more thought, then YAGNI will just have to deal with it.
The Ideas Behind YAGNI
To give it even more context, applying YAGNI to everything you do is a recipe for a dish of spaghetti code. In my opinion the two main ideas you need to consider before reaching for the YAGNI stick are:
- granularity
- balance
Granularity
It makes a lot more sense to me to apply YAGNI to much larger concerns. Let’s make our application scalable to 1000 requests per second. Whoa, YAGNI – it is only ever gonna be used internally and there are only 100 users, not necessary. We as developers tend to sometimes let our love of playing with cool technology run away with us and end up using a proverbial bazooka to clobber a fly. YAGNI can help us avoid this, but it is only really relevant when we are talking about things that can take significant time, money or work. I am referring to coarse-grained concerns – major features, changing project direction, radical technology changes. If you’re dealing with any of those or similar than by any means apply YAGNI and see if it still makes sense, otherwise there are perhaps other practices that can take precedence.
Balance
You have to balance the YAGNI mentality against reality. You often CAN anticipate which way the project is likely to go in the near future and it might make sense to build particular things now to cater for this. You may have capacity now but will not necessarily have it later. You may have some expertise within your team at the moment that will not be available down the track. These things can weigh in against YAGNI. And when we are talking about finer grained features (i.e. the actual code and low level design of the system), then the *abilities should always take precedence, maintainability, testability, usability, readability etc.
The Agile Practice Stupidity Threshold
No matter what practice you use you should always understand the implications behind it and in what context the practice is best applied. For example, TDD is a great practice and you can use it to evolve better designs through writing the tests first. However, would you ever use TDD to evolve attribute readers or writers – of course not! More than that, there is a certain level of code that is just too simple to require being evolved through TDD, there is simply no need. But, if you use TDD without thinking you can find yourself doing exactly that, which would just be stupid and a bad use of TDD.
Every practice you use, including TDD and YAGNI has a certain threshold which I call the stupidity threshold. While you’re using the practice as a tool giving due consideration to all other concerns, you’re fine. But, as soon as the use of a particular practice becomes an objective in and of itself, you have crossed the practice stupidity threshold and will find yourself in trouble eventually.
Image by hiddedevries