March 02, 2004
Defending YAGNI
Apparently, YAGNI is arrogant. I feel that given the amount of stick it’s received over the last few days, I should put a word in for it.
First, let’s clear away the straw men, and present a reasonable argument for “You Aren’t Going to Need It”.
- You can build it now, or you can build it later
- If you build it now, it will take ‘x’ amount of time
- If you build it later, it will take ‘y’ amount of time
- You don’t need it now
- That’s ‘x’ amount of time that could have been spent on something you do need now
- Or, that’s ‘x’ amount of time earlier that you could have delivered working code, if you weren’t busy doing something you didn’t need to do
- If you do it, and it turns out you don’t need it after all, that’s ‘x’ time wasted
- If you don’t do it and it turns out you do need it, you’ve wasted the difference between ‘x’ and ‘y’
- Additionally, unused code, or code that is complicated due to requirements that are not yet realised:
## Is still a potential source of bugs
## Slows development
## Hinders maintenance
YAGNI tells us that too often we over-estimate the difference between ‘x’ and ‘y’, and we over-estimate the probability that we will actually need the thing that we envision now. Chances are that later, when we need it, it will take a completely different form because of the way it must interact with other pieces of the program that have been created since.
YAGNI is a defense against pretty much every programmer’s (including my own) desire to find general solutions, even when we are being paid to do something specific. We often fail to notice that the cost of making something flexible enough to meet future requirements now is about the same as it would cost to add the same flexibility later. We vastly underestimate what a good programmer can do with a codebase given a free afternoon and a good refactoring-aware IDE.
Is it really that scary now? Stripped of the zealotry on both sides, it’s a pretty simple equation. In many cases, the values of x and y are pretty close together, even indistinguishable. This is the case with most individual ‘features’ of a program. In many others, there are some basic design and factoring steps you can take to move them closer together and avoid problems in the future. This is why we tend to layer systems and encapsulate components.
Of course, applying any doctrine blindly is dangerous. In some situations, such as when you are publishing interfaces to a third party, you just can’t bring the two values closer. You just have to bite the bullet and decide if you’re willing to wear the risk of spending the time on something that you may not need. Similarly, the cost of adding things “later” that pervade an entire program, like security or robust error-handling, spirals out of control the bigger the program gets, and must be catered for from the start.
YAGNI protects us from wasting time, and protects us from over-architecting. Applied blindly, it can lead us to code ourselves into corners that take an age to dig out of. Taken to ridiculous extremes, it results in overly simplistic software that collapses under its own weight and has to be rewritten from scratch. Used rationally, however, it tells us not to implement features or architect clever “flexible” solutions just in case: it asks us to keep in mind that there is a cost to everything, and that we should prioritize development of things we know we need over things we might need later.
It’s not a radical idea, really.
Posted to nerd at March 2, 2004 12:27 AMCharles Miller defends YAGNI: It turns out that there's no need for me to ever write up a good defense of the "you're not going to need it" strategy, because Charles Miller has already done so. Sure, nothing applies 100% of the time, but...
From: Blue Sky On Mars at March 2, 2004 07:10 AMOn YAGNI: Sometimes during design and development of an application you encounter something, maybe it's a feature, perhaps its a design decision, whatever it is there is a certain "cost" involved. Should the "cost" be paid upfront, when it is...
From: Adventures as me at March 3, 2004 02:41 AMAgreed. In fact I often -- not always, but often -- find that 'y' is less than 'x', because later in the project you have a better idea of exactly what it is required.
Posted by: Alan Green at March 2, 2004 06:26 AM (#link)On my projects, I've seen a trend of folks building something cool that we may or may not need to avoid building something that we don't know how to build. Building the cool thing that we know how to build is so much more affirming than facing down the thing that looks like a beast in the corner. If I build the cool thing and end up struggling with the beast, at least I, and anyone else who cares to look, know that I knew how to build the cool thing.
Posted by: Tina Coleman at March 2, 2004 06:54 AM (#link)It's interesting - pro-YAGNI individuals seem to always cite cases where developers over-built and either wasted time creating something that wasn't needed, or screwed the project up wallowing in unnecessary stuff.
Meanwhile, back on the flip side, detractors talk about the cost of postponing items, and the times they saved their asses by anticipating future more than YAGNI would seem to imply.
From where I sit the anti-YAGNI faction tells a story where they learn from their mistakes, and apply lessons learned to future projects. Over time they learn how to order project implementations, and learn what features are best done early (even if they aren't used, or used heavily, early on). I don't mean this to sound offensive, but it may come out that way - but the YAGNI story seems to be that developers are incapable of learning, or are constantly put on radically new projects and so can't learn. Hence you have a rule of thumb of when in doubt, Ya Aren't Going to Need It.
Put in those terms, YAGNI seems like a tool to fall back on when you're out of your depth. This describes the bulk of XP projects I've studied, but doesn't seem to map to most real IT projects I've been involved in.
Posted by: Mike Spille at March 2, 2004 07:18 AM (#link)"Used rationally"
Hmmm, how rational is the case that YAGNI 'protects' against?
Is it rational to implement features just-in-case, forget that everything has a cost, or prioritize development of things we 'might need' over things we know we need?
Given those behaviours why would we imagine YAGNI would be applied rationally?
Posted by: Isaac Gouy at March 2, 2004 07:57 AM (#link)"It’s not a radical idea"
Agreed - it's long been known as "defer anything you can get away with"; and has a counterbalance - "no surprises".
Thanks for the writeup Charles. Regardless of the silly sounding name it's a pretty simple concept that makes sense in most situations. There's too many people making emotional arguments against a principal that's really pretty basic and straightforward.
Posted by: Glen Stampoultzis at March 2, 2004 09:27 AM (#link)Cedric is again writing his garbage and we pay attention. I wonder why?
Good response Charles.
Thanks Charles, you wirte it better than I could have hoped to.
As you point out, there is a big difference between a framework development (a public API) where the possible uses and users are broad, and code for whom the clients are controlled. In the latter case, it is possible and desirable to leave the implementation decisions till extremely late, when the concrete requirements are as well known as possible, and absolutely required. In the former, it is desirable to publish as late as possible. As Alan points out, its often better, easier and quicker to implement something you now have a solid, well developed and fleshed out requirement for.
I have seen plenty of cases where an early implementation becomes the only possible implementation simply through the inertia of existing code and the the conservatism of developers who will not/cannot risk breaking something. YAGNI breaks this cycle in combination with unit tests and refactoring.
The other thing that strikes me about these YAGNI critics is the implicit egotism of their position: that they don't need this stuff because, they are good designers, and that XP is an excuse for bad design by people who have given up hope of this concrete ideal. Well, I have seen some crap designs that work very well, and some great designs that don't, and vice versa - but YAGNI isn't about design, its about features. Good programmers write good designs by rote, bad ones by accident. But designs are never simply good/bad in a concrete sense, only in their fitness for a particular concern, and even then a design is usually asked to fulfil not just a singular concern but multiple, crosscutting and often orthogonal concerns.
Posted by: Jed Wesley-Smith at March 2, 2004 04:44 PM (#link)Why does no-one talk about YDNIAA (You Didn't Need It After All)?
Agile methods in general are a very good way to do defensive development. I'm talking about development in the face of changing requirements, which in some cases can change on a daily basis. My work list never gets updated until I've been asked for the feature *twice*, simply because a few days down the line is is likely that I will be told it wasn't needed after all, or was a bad idea. That way I avoid the wasted time of developing the feature twice, or undoing it.
When you're riding on a turbulent sea, don't stick your oar in until you're sure. YAGNI is a perfect example of this.
Posted by: Chris Harris at March 2, 2004 07:28 PM (#link)You should assume You-Probably-Aren't-Gonna-Need-It (YPAGNI) and be prepared to spend some very small amount of the customer's money as insurance against catastrophic requirement discovery.
I want to emphasise three aspects of that statement: the up-front cost is small; the cost of satisfying the potential requirement would be huge; and the developer makes the decision.
The first two of those aspects are about mitigating risk: anyone who has bought one Monopoly railway station to prevent the opponent obtaining all four is familiar with the logic.
Developers should decide when that risk mitigation is warranted. Customers decide what requirements get built and when; but developers have a duty to reduce, as best they can, the overall cost to the customer. Some might argue that the overall cost extends only as far as the implementation of the stated requirements; I think it extends further than that. If developers are entitled to decide when it is worthwhile commenting their code, they are entitled to decide when it is worthwhile to make their product a little more amenable to future enhancement.
Posted by: David Pinn at March 4, 2004 01:48 PM (#link)What a lot of detractors seem to miss is the conventional wisdom that YAGNI turns on its head. That assumption is that the change of cost of software over time is exponential. This may have been true back in geardagum, but, with modern OO methods and tools, doesn't seem to apply anymore. So, what YAGNI is really trying to say is that the software change curve is closer to O(n) rather than O(n^i). This being true(is it?) then changes to code later are no more expensive than changing the code now.
Posted by: Keith Sader at March 4, 2004 11:48 PM (#link)Keith, that's a good point. In fact, IIRC it was Ward Cunningham who stated this explicitly in his Artima interview series - that change later in a development cycle is less experience than people perceive, at least under XP. YAGNI definitely ties into this.
Personally, I don't buy it. The premise works for simple applications, like Robert Martin's FitNesse code. I don't think it scales well to larger projects at all. OO methods and tools have made development, refactoring, and changes easier, but I don't think they've altered the fundamental nature of the curve (nor do I think XP does so). It all appears to me to be an exercise of extrapolating the results of small projects and thinking they apply to larger and more complex ones.
There are some excellent points on this page - I may save this and read it each time I start a new project.
I think I go along withDavid Pinn's post.
I try to use a 2-sided approach: to the user I say "YANGI", but to myself I say "Suppose they really _do_ need it? What can I do now that would make life a little easier if that turns out to be the case?"
This isn't the same as trying to build the Completely-Generic-Solution-To-Every-Problem. It's just a little nudge that makes me look at my design again and ask "Is this extensible?"
That can't be a bad thing, can it?
I think YDNIN (You Don't Need It Now) is more accurate than YAGNI in this sense.
Posted by: Ryan at October 21, 2004 06:02 AM (#link)