You Are Gonna Need It

Terse Summary: If it's a known requirement, you are gonna need it. YAGNI protects against imagined requirements, not known requirements. -- EricHodges

--- Here's some imaginary person's emotional reaction to YouArentGonnaNeedIt:

Some people here are saying that it makes sense to implement only what you actually need to build the features you are currently signed up to build. They are saying that if you see the need to do something that isn't on your plate, you shouldn't use your own judgment whether to go ahead and do it.

It's obvious that it is easier to put features into the system now, when it is simple and when it's clear in your mind, than to wait and put them in later. Later the system might be crufty and the features would be much more expensive to put in. Later you might not remember how to do the thing, or even what it was, and you would have to reinvent the idea. You might not even be able to get the idea back: it might be gone forever!

If I am working on a class and I can see how to make it better, or more general, or more potentially useful, I should make it better. The idea is to build a quality system, isn't it? Then it's just flat wrong to say that I shouldn't make things better. To say I shouldn't do it is to come out against quality. It's not only wrong, it's almost immoral.

Here's some real person's emotional reaction to YouArentGonnaNeedIt:
It is obviously better to put anything you need now, as you are still familiar with the codes you are writing. Most people had hard time to remember every function in a class after 3-4 years of developing thousands other classes and codes. So they'd need to reread the code, refamiliarize, and reunderstand the code and that might takes around 10 minutes in a very simple code and days on a real program. That's a waste of time.
The reason is obvious, customers either tend to seek program that have a lot of feature or programs that have the features they need. For the first one is obvious why YAGNI is stupid thing, but for the second, it's not obvious but it's because no customer would never even thing to try to buy or download a program that have no feature that he need. It's about the users, not the developers. The users wouldn't even think of trying to request that feature, because they know that the developer would need time to code that feature and they need the program immidiately. Even though the developer could do the feature in short time or the users have time to wait, the users is not likely to use the program since he know that the feature is newly implemented and is likely to have bugs, the users would then choose competitors product since they know the competitors product natively support that feature and must have gone through numerous bugfixes before he needs the program (small change to improve things is not considered as adding features, it's more likely to be called fix or debug).


The YouArentGonnaNeedIt rule is about putting in features which, by your own recognition are not needed for the task you are working on, but which you perceive may be useful in the future. It could be about something else, but XP named it and that's what it is about. Let's explore what would have to be true to make adding the feature make sense. Help me out here. Here are some starting ideas:

Easy Now Hard Later
It could for some reason be more difficult later to put the feature in than it is now.

What are the characteristics of a system that gets harder to edit as time goes on, and how can that be avoided? Could addition of unused code be one of those characteristics? How can we decide that this feature is more deserving of easy implementation than the one that is made harder by the addition of this one? (Consider the case where deploying the change is the problem; see YagniExceptions and CostOfChangeFlatteners?. -- RonCrocker)

If you really think you'll need it, make sure it's easy to add it. Encapsulation rules! RavioliCode can certainly help here, so long as the raviolis (modules/functions/objects/features) themselves are flexible and easily accept new raviolis (modules)

[Certainly, one should take care not to paint oneself into an architectural corner--it is easier to make a change to code that hasn't been deployed. On the other hand; far too many projects try to be too farsighted and worry about developing the PerfectArchitecture, one which goes far beyond the immediate needs. Kind of like ignoring the red light in front of you because the traffic light down the road is green.]

Really Will Need It
I might know, having looked ahead in the requirements, that the feature absolutely will be required.

But when is this sufficient to justify diverting effort from whatever task I originally set off upon?

[If it is down to a choice between implementing feature A and feature B, both in the requirements and of equal priority, the choice of which to implement first isn't necessarily YAGNI. If it is in the requirements, then you are gonna need it; implementing B before A doesn't strike me as a problem; unless there is some other reason why A should be done before B. YouArentGonnaNeedIt generally refers to implementing things that aren't necessary to meet the customer's requirements.]

Might Lose The Idea
I see now how to do this cool and useful thing. I might forget and have to reinvent it, or worse yet, it might be lost forever.

How valuable is the cool thing if you never need it? Are there only a finite number of good ideas left in the world and we must rush to do each one? Are you out of note paper?

Product Is Framework
I'm building a framework or class library, and there is no customer available other than me. The framework will be more valuable if it has features that people look for when they need them, so we should put in as many features as we can think of.

Is time to market important? Would less capability sooner, with frequent releases, be better, or worse in your market? Would adding features when customers actually need them be more effective, or less, than adding them on speculation?

[A programmer's customer is whoever is paying for his/her time (directly, or indirectly by purchasing products made by the programmer's employer); a programmer's customer is only himself/herself when it's his/her own time. While it is often good to SharpenTheSaw when working on something for someone else; the need to efficiently complete an assigned task doesn't make the programmer a customer in equal stead with the one who pays the bills.]

[If you truly are the customer, than implement whatever you want. It's your time and your dime.]

There Is No Customer
This is a new idea, for which no customers even exist. The product is my vision and I have to follow my star.

If the software has no intended use, i.e., no customers exist, how can there be any requirements at all? I can't think of any software (including "Hello World") that does not have an intended user.

There is no SINGLE Customer
You don't just have one customer or benefactor, you have hundreds, perhaps even thousands of individual or corporate customers (like Microsoft or Rational) and no one single customer dictates the features to add. There may be many people screaming for it and many people who dont care, and still others who dont want it.

[As always, features must be traded off against schedule and resources; when programmers engage in GoldPlating they risk violating the agreed-upon priority among these three forces]

Check the questions above about time-to-market and real feedback. Could they help make you more successful than just listening to your star?

You ARE The Customer
You are developing something for your own personal use, OR you are developing a system for which you will be one of many users who have a say in what goes into it.

If you are the customer, you should know what you need and what you don't. Why is this different from the cases where anyone else is the customer?

My Boss Is An Idiot
My boss is just a guy with money and a skill for selling. He got me in here because I understand the real market and can write a system for guys like me.

Is this yet another case of the Framework and No Customer ideas? Is it valuable to recognize that without feedback from people who are actually using the stuff, even your educated guesses add more risk than is necessary? Can you find Alpha- or Beta- users? Can you get a bunch of guys together at the pizza place? How can you confirm that you really need the idea instead of just grooving on how spiffy it is?

[It is a well-known AntiPattern that programmers (and marketing folks, and managers) think that they are right and the rest of the team are clueless boobs. They may well be; but that's life for you; very few programmers in my experience have as much domain expertese as they think they have.]

{Thusly the need for requirements that are stated by the decision makers who are going to actually use or sell the product. This requirement set needs to state what the CriticalSuccessFactor for the product is, what it absolutely has to do in terms of numbers, and what it may be asked to do in the future. Without having a good set of requirements before you get started it doesn't matter how much nor how little domain knowledge the dev team has; the turkey is gonna blow up.}

You are coding for fun
Business value doesn't matter. Time to market doesn't matter. Coding an elegant framework, delightfully simple in the underlying patterns but at the same time dizzyingly complex in the capabilities it opens up (and you often exploit) is its own reward. You not only need it, you crave it.

Implementing a more general solution reduces and simplifies the code
The general solution might be more elegant. It might be more fun to work on. Later serendipity might kick in and the generality might find other uses. Did Bill Joy have to invent Java to program set-top boxes? No. Did Larry Wall need to invent Perl to automate his sysadmin work? No. Did we really need the more general web protocols for publishing some high energy physics papers on the web? Nope. These are all cases where YAGNI was thrown the wind, and the world is a better place for it.

Is the goal of elegance best-served by the addition of this feature at this point in time? Might adding it cause you to fall into a pattern of thinking such that you'll design future features in less-general ways without realizing it, because of this one's presence?


Note as well that a key and ever-present assumption of XP is the presence of a customer. It is fair to call YAGNI into question if there is no customer. -- RonJeffries


Thanks to the original author! What you say makes perfect sense as long as we all know the meaning of quality. (In your text, you've used several rough synonyms for this as well as the specific term: 'more general', 'better', 'more potentially useful'.)

Ahhhh, but there's the rub. Quality is terribly non-obvious. Your best guess at what quality is today is very likely to disagree with your best guess tomorrow, (let alone the difficulty of reaching agreement between two people or god forbid, fifty).

We can read the heavy methodology books till the cows come home, and we *still* won't know what quality is. Each of these is chock-a-block with definitions. I'm sure you can quote yours from your favorite methodology. Unfortunately, they all have the feeling of the famous supreme court ruling on obscenity: I'm not sure what quality is, but I know it when I see it.

XP doesn't per se define quality. Instead, we define a process that we continuously evaluate and improve. That process seems to pretty consistently create something that we agree is quality.

YAGNI is a part, one part, of that process. -- MichaelHill


Ah, quality. Quality, as Pirsig says, is what you like. To me, actually, quality is what the customer likes. That's why it's very questionable to work on something that isn't what the customer asked for - because your contract is to deliver what the customer likes. -- RonJeffries


YouArentGonnaNeedIt and YouAreGonnaNeedIt are both predictive in nature. The hypothetical "YouDoNeedIt" and "YouDontNeedIt" would be easier to sort out, if only a little easier. Quality resists precise definition, but there are acute moments when it or its absence is felt. These are moments of acceptance or rejection by the party whose reaction counts (whoever that is). Because software development takes time, these moments are always in the future, and so prediction cannot be eliminated. The difference between YouArentGonnaNeedIt and YouAreGonnaNeedIt reminds me of the difference between speculating on stocks and speculating on their options. When you buy a stock, your loss is limited to your capital investment, while certain options carry unlimited liability. YouAreGonnaNeedIt, unfortunately, is a tech stock option with an observable runaway characteristic. Here is a classic tradeoff between risk and reward. It's not that nobody should trade options. It's just that it's not child's play. One of the things that's truly extreme about our software development industry is the median age and experience metric, and it keeps going lower and lower. The techniques must fit the force using them. Sorry, kiddos.

-- WaldenMathews

Isn't another driving force to purposefully leave functionality that can be documented and stubbed out now for future actual implementation? In other words, I may include in a method which the current scope of the object doesn't require. I do, however, see that for maximum flexibility, I may need that method. I stub it out, comment it for future maintenance, and probably label it non-public (so code doesn't accidently call it, and my public API isn't contaminated). -- MichaelSuzio

I would avoid this practice. These stubs only cause confusion for later maintainers. Why is this stub here? What happens if I take it out? It is usually far easier to add new code than delete old code, so if you don't need it right now, don't spend any effort on it. -- WayneMack

If the stub can be added without breaking anything, then consider that YouArentGonnaNeedIt - you can add it later if you really do. If adding the stub would make a shared library incompatible with the programs that use it, then your customer includes the developers of those programs. Perhaps one UserStory says "Updates to libfoo should be binary-compatible unless... [mitigating circumstances]." Then you have a case for adding a stub, but now it's an actual customer requirement, and you can still DoTheSimplestThingThatCouldPossiblyWork. But see also BuildForTheFuture. -- JoshuaJuran


An interesting example came up in an interview the other day. These people had never worked on a switch before. And no customer understood the issue as it's not obvious without experience. The issue is managing a rack of cards. The naive method is to only represent the inserted cards. It's only later that you realize you need to represent the slot and not only the card so it can be preconfigured and have an inserted/failed state, etc. It's only much later that you realize the need for proxies for things that may not exist at all. This is a common mistake. But it's also fundamental, like gravity. If you don't have these concepts in from the start you are sunk because they impact everything. And of course they were late and eventually failed. The head guy argued, "You aren't gonna need it, so why bother?" Under the self-protecting rules of XP I'm sure there is some reason why these people should have known this or reacted better, but it's usually not that simple. -- AnonymousDonor


See TwoIsAnImpossibleNumber. --- That is actually the best argument for moderation of YouArentGonnaNeedIt I've seen. Right NOW I only have two (or three, or some definite x) cases - why should I write code that's generalized to N cases because I might need it some day?


You are coding for fun...

Ach, give the guy a break! Let him code whatever his whimsy tells him to code, as long as


[replicated (in part) from CommentsOnPrincipleSix]

I don't know about a pattern per se, but I certainly know about limiting the scope of planning for reuse. Embedded systems is self-limiting in this respect anyway, since one piece of hardware may be wildly different from another one in both operation and substrate. Of course I look for patterns to replicate: user interface, motion/process control, real world feedback, etc. Often, though, the client says, "Look. This thing is going to be a widget. Just a widget, only a widget, always a widget, never anything other than a widget. Build me a widget, and I mean like right now."

I have to respect that. Even when the project is to build a (sic) platform for other products there is a limitation on the projected use of the platform. "This new widget is going to be a pump controller. That's all. It might be a syringe pump. It might be a systaltic pump. It might be a high volume pump. It might pump blood. It might pump saline. It might pump plasma. The only thing we know for sure is that it's gonna be a pump."

This tells me that I need to plan for reuse of my software system in the context of being a pump, not a general motion controller or a radar direction finder or a navigational aid or a fire control center. The damn thing is a pump. With this limitation in mind I can ask questions about how pumps might be configured, how they might be used, and what kind of flexibility I need to design into my system. But when that's all done I end up with the design for a pump, and that's what I build.

later...

As an extension to this blather, let me tell you about a little subsystem problem I had with this same pump project. Another engineer -- brilliant guy, designed almost the entire motion system from a clean white sheet of paper -- created a CPU-to-CPU communication subsystem for Master to Safety linkage. [Note: most Class II and above medical systems have at least two processors so that there is independent confirmation that a treatment is being delivered correctly.] He Did The Simplest Thing That Could Possibly Work, and it did - for about three minutes. His approach (which had to be implemented on both CPUs, of course) involved a round robin, fixed time slot kind of messaging scheme with just a handful of message types being sent back and forth. Rather than deal with complex messages he ignored them. We didn't need them at the time. Rather than deal with outstanding messages awaiting response he ignored them. We didn't need them at the time. Rather than deal with the critical timing and latency issues involving extended message sizes he ignored them. We didn't need them at the time.

Then we had to add another message type.

The whole messaging subsystem collapsed because it couldn't handle any of the requirements of handling one more message type. I had to ashcan all of his work and start from scratch to get the Master and Safety talking again. I had to create a messaging scheme to handle not only the message types I knew we had but also the ones I could extrapolate from our projected usage. Had this been done originally a whole boatload of code need not have been wiped clean and redesigned from both the Master and Safety devices.

Now, this was not a case of goal posts shifting. Anybody could have projected the need for complex message types in M-S comm by pretty lightweight analysis of the tasks being coordinated between the two processors. In this case the DoTheSimplestThingThatCouldPossiblyWork approach flunked miserably. YouArentGonnaNeedIt was a falsehood; we were gonna need it, and did. I suffered the consequences. The Next Time I'll Know Better(tm).

-- MartySchrader

It reads as though you've misinterpreted what "work" means. Ignoring things that are known to be required is not at all what YAGNI recommends. Furthermore, "I need to add a feature, so I'll ditch all the existing code" misses several quite crucial points about professional software development.

Perhaps you didn't see the part where I said the comm system simply couldn't support the "additional" functionality required by the continuing development of the device. You are correct in that the statement at the top of this page applies here. The "simplest" comm functionality was only good for the simple testing of subsystems that had been done until I started implementing actual, real, verifiable, FDA-approvable safety processing. That's when the little bugger showed its flaws, and that's when I had to scratch it and start over. And start over I did, because nothing from the original mechanism was salvageable. Believe me, I would have reused the code if I could. That just wasn't possible. -- MartySchrader


What if you're integrating a large subsystem which has a huge number of set requirements. For example, say W3C would not allow you to publish a web-browser unless it adhered fully to the CSS2.0 standard.

My previous experience with such a system has shown that the entire integration will take at least six months and involve both core functionality integration and a lot of GUI work. In my specific case it's a matter of "implement all this, or you aren't allowed to utilize the subsystem". The rules are set by a third party providing the subsystem services, not by the customer nor the team. The customer wishes for the system to be integrated and in effect we *know* we have to implement support for all the required features, or drop it completely. Would it still be wise to adhere to YouArentGonnaNeedIt at all times, when it's quite possible to make decisions that prepares for the known requirements? If the feature is suddenly cut, we'd know we have to rip it all out regardless of how long it took to get as far as we did, so losing time is not really an issue, or?

-- AndreasAxelsson

If it's a known requirement, you are gonna need it. YAGNI protects against imagined requirements, not known requirements. -- EricHodges

Both Marty's and Andreas's examples don't fall under the YAGNI category. Andreas's is easiest: the business W3C requirement calls for full CSS2.0 implementation. Hence it's a requirement, and all features must go in. Now it's just a question of the ReleasePlan. Marty's example falls under the case of inadequate analysis of the system. A proper analysis would have discovered the need for complex messages to be sent -- and I see nothing in XP to preclude a proper analysis of the system. -- AmirKolsky

I believe that we may be mixing two different concepts, "delivery of software for use" and "internal builds." Delivery is usually based on factors outside the developers' control. For example, a "delivery" may be required for an actual sale, a sales demonstration, a trade show, an internal budget review, or putting the project on hold. These can be accomplished with working software even if it does not have all of the "requirements." Each "internal build," however, should have a tightly controlled requirements set. It is difficult enough to get everything selected done in a 1 - 3 week cycle without adding anything else to the mix. The cycle is short enough, though, it is not painful to defer an idea to the start of the next cycle. The new idea can be evaluated on equal footing with all previous unimplemented ideas at that time. The idea is that it is better to have a small set of fully functional capabilities (nearly at all times) than to have a large set of partially functional capabilities. The development team needs to stay tightly focused on completing "internal builds" so that when a "delivery" is requested by an external force, the new software is never more than 1 - 3 weeks from being ready and the old software is never more than 1 - 3 weeks out of date. Anyone who has ever struggled to get broken software working in time for a trade show or key customer demonstration can appreciate working only on the minimal set requirements to get the job done, at any single point in time. -- WayneMack


I think it is a matter of probability and your estimating ability. One has to weigh the pros and cons of adding "future-proofing features" with a business mentality, as one would with any other investment. Will the effort pay off? When will it pay off? How good are you at estimating future payoffs, etc. If you are in uncharted waters, lean toward Yagni. DecisionMathAndYagni


There's one trap in the case when you're extending code.

Say you have a programme that does X, Now you want the programme to also be able to do (at least) also Y. X and Y both have common functionality f, plus some unique code x or y respectively. (ie. it could be implemented as f+x and f+y, so that f+x+y will give you what you want.)

Your next step should now be rewrite X as f+x and test. The programme will be more complex , but should do exactly the same as before. Finally, extend the programme to f+x+y and test again.

The problem occurs if your code remains in the f+x state for longer periods of time. This could happen for instance if you are still busy fulfilling some other prerequisites for y, or if you get called away to do something else.

At this point, someone else might come along and state that YouArentGonnaNeed? f to do X properly, and will refactor f+x back to X, leaving you back where you started.

I've experienced a case where someone refactored code back like this very aggressively, basically making it very hard to do any extentions at all.

In a more limited sense, it is useful to write code *slightly* more general than that you're going to need it. Don't overdo it, but a little more generality gives your code a bit of a sticky 'feel' to it, so that it's easier to combine with other bits of code. Overly agressive YouArentGonnaNeedIt leaves your code 'feeling' smooth with no easily visible paths to extention or aggregation.


Kindly don't flame me, I never coded much more than simple basic and only spent about three minutes reading this page, but isn't YAGNI what got us into the y2k mess, people assuming they never needed to scale timeframes beyond 15-20 years? Even if you don't plan for YAGNI to lock you into something, sometimes time has a way of its own. -- anonymous coward

Nope, we're talking about Yagni as it applies to code design, not to requirements.

Okay, now how do we separate the two? How do you distinguish between them? Where does requirement end and coding "discovery" begin? We can't apply glib answers to complex questions, even with 20/20 hindsight.

Do I need a date manager class, should dates be immutable value objects, can I get away with a double? These are design quesions covered by Yagni. Do we need to save the space the first two digits of the year uses, do we need to print dates in ISO format? These are requirements which are specified by the customer (albeit, the space is probably indirectly specified by a customer's cost/hardware requirements). Yagni doesn't apply to those. Sorry if I was glib, I was somewhat ticked by by the eraser phrase and the conmplete lack of capitalization in the sentence; I assumed if the person didn't even take the time to write well, he probably didn't think about the question enough to warrant more than a terse answer. .

Perhaps it is worthwhile saying that with a BondageAndDisciplineLanguage, one does not necessarily have the luxury of being able to refactor easily; with that constraining environment, painting oneself into a corner ends up being very expensive. -- AndreThenot?


The PragmaticProgrammer answer to YouArentGonnaNeedIt: Do It or Get Bitten In The End. Some features are easier to add now than later: http://www.pragmaticprogrammer.com/articles/mar_03_trip.pdf

How so? Can you name one? What is the definition of now versus later? For example, before/after listing requirements, after release, etc. Please specify.

I'll bite. I generally adhere fairly strictly to YAGNI, but one area in which I do not is I18N of display text. I always wrap all display text in I18N functions from the start, regardless of whether there's a defined requirement for multiple languages.
Why? Because this is one of the few things that really does get harder to change as the codebase grows. If I internationalize later, then it's very, very hard to make sure that I haven't missed a string somewhere, and I don't see how to write effective tests to check. Setting up I18N at the beginning, and enforcing the discipline to wrap all strings in appropriate functions, involves a small amount of overhead up front, but in this case, the overhead early in the project is much less than the cost of a later change.
Note that because I tend to write end-user applications, and mostly Web applications at that, I can be almost sure in most cases that I18N will be a worthwhile feature to have, as I hope that people from all over the world will be able to use my software. Perhaps if I were working in a different sector, I wouldn't bother. --MarnenLaibowKoser


Compromises. Life is based on compromises. Sometimes YouArentGonnaNeedIt, sometimes YouAreGonnaNeedIt.

Our professional duty is to tell, as best as we can, the difference between the two and LetTheClientDecide if he wants to make the investment or not. Remember TheConsultantsMantra: "It's okay -- we bill by the hour."


Tough Decisions

Consider you are developing a website based on text files. The site will grow with time, but for now it is fairly small.

YouAreGonnaNeedIt (maybe, maybe).

Your gonna need a database, eventually.

The question is.. can you develop the site without the database and then merge the text files into the DB later? Or should you go right ahead and do the database from the start?

It's always not a clear answer... sometimes YouAreGonnaNeedIt and sometimes YouArentGonnaNeedIt, but will (possibly, maybe) later.

Usually it is a matter of compromising. If you are familiar with the YouArentGonnaNeedIt thing in question, you might start off with it if it doesn't take that much extra time to use the YouArentGonnaNeedIt thing. This goes against the YouArentGonnaNeedIt philosophy, but it also allows you to learn about the bigger longer term solution right off the bat.. rather than developing two separate solutions.. one dumb simple one first, and a more advanced but separate and incompatible solution later.

If the two solutions (YouAreGonnaNeedIt and YouArentGonnaNeedIt) can be merged.. then the final long term solution (compromise) is better off.

However, many web startup companies fail.. and buy too much stuff.. three servers, dedicated hosting.. YouArentGonnaNeedIt until you get big. Design the first solution in a way that it is merge-able (into the YouAreGonnaNeedIt solution) later. That way, if YouArentGonnaNeedIt right away, at least you have a half cooked plan in mind so that if YouAreGonnaNeedIt later, at least there are possibilities of making a big long term solution work.

A partner and I are facing this right now. We're developing an online automated vehicle location system that needs to record the movement of a substantial number of vehicles for each user (fleet operator). When we were first talking about it we thought we might whip up something that could operate with flat files or XML records or some such, but it quickly became obvious that if we don't implement some databases right now then we'll be eating a huge quantity of labor later on trying to retrofit it. I'd rather not be facing that hassle if we can DoTheRightThing up front. It delays service launch, but at least we'll be ready for volume when it comes. And come it will. Heh.


Decisions Take Too Much Time

Consider throw away programs... some of my throw away programs end up being refactored into long term libraries. Instead of throwing away your throw away programs because you think YouArentGonnaNeedIt, keep them - hard drive space is cheap. When YouAreGonnaNeedIt at least you have it there (and some throw away programs can act as test cases even though you might not have thought they would be useful).

It also takes a lot of time you consider whether or not YouAreGonnaNeedIt.. so if it takes less time to just declare that YoureGonnaNeedIt? some time.. then keep it: especially if the cost of keeping it is really low and especially if it saves you time just making the decision to keep/do it.

Sometimes there is really no way to know if YouAreGonnaNeedIt until you JustDoIt and feel the situation out.

Does this not lead to ThrowOneAwayInPractice or some sort of SpikeSolution research?


See: BargainFutureProofing, DecisionMathAndYagni

CategoryRequirements


EditText of this page (last edited February 22, 2012) or FindPage with title or text search