(often abbreviated YAGNI, or YagNi
on this wiki) is an ExtremeProgramming
practice which states:
- "Always implement things when you actually need them, never when you just foresee that you need them."
Even if you're totally, totally, totally sure that you'll need a feature later on
, don't implement it now. Usually, it'll turn out either a) you don't need it after all, or b) what you actually need is quite different from what you foresaw needing earlier.
This doesn't mean you should avoid building flexibility into your code. It means you shouldn't overengineer something based on what you think you might need later on
This also follows the KISS theorem: Keep it simple, stupid!
There are two main reasons to practise YagNi
- You save time, because you avoid writing code that you turn out not to need.
- Your code is better, because you avoid polluting it with 'guesses' that turn out to be more or less wrong but stick around anyway.
A scenario from RonJeffries
explains the practices:
You're working on some class. You have just added some functionality that you need. You realize that you are going to need some other bit of functionality.
If you don't need it now, don't add it now. Why not?
- "OK, Sam, why do you want to add it now?"
- "Well, Ron, it will save time later."
But unless your universe
is very different from mine, you can't 'save' time by doing the work now, unless
it will take more time to do it later than it will to do now. So you are saying:
- "We will be able to do less work overall, at the cost of doing more work now."
But unless your project
is very different from mine, you already have too much to do right now. Doing more now is a very bad thing when you already have too much to do.
And unless your mind
is very different from mine, there is a high chance that you won't need it after all, or that you'll need to rewrite or fix it once you do
need it. If either of these happens, not only will you waste time overall, you will prevent yourself from adding things that you do
need right now.
- "But Ron, I know how to do it right now, and later I might not."
- "So, Sam, you're telling me that this class you're writing is so complex that even you won't be able to maintain it?"
Keep it simple. If you need it, you can put it in later. If you don't need it, you won't have to do the work at all. Take that day off.
To the tune of "We're Not Gonna Take It" by The Who, from the classic rock opera "Tommy", which is highly recommended.
You ain't gonna need it!
Never did and never will!
Don't need featuritis
And the users will never tell.
You ain't gonna need it
Half a feature's
||: Test me... Code me.. Refactor me... In'grate me... :||
List'ning to you, we get the features
Planning with you, we get priorit-eees
Coding for you, we build releases
Pairing for you, we make deliver-eees
- Phlip (on the XP mailing list)
P.S. There is another song with the same name, featured in the teen testosterone flike "Iron Eagle", "Twisted Sister". ''Both bands did (rather
different) songs of that name; the takeoff here is based on the rather earlier one by The Who.
YouArentGonnaNeedIt in the context of the other ExtremeProgramming practices
You have a ReleasePlan
: each UserStory
has been assigned to an Iteration where it will be done. Under the current IterationPlan
, you are working on an EngineeringTask
that you signed up for, in support of one of the Iteration's UserStories
. As always, you have signed up for as much IdealProgrammingTime
as your LoadFactor
indicates you can accomplish.
You are evolving the system to have the new functionality required by the UserStory
, defined in the EngineeringTask
. You add capability to any class we need to, directly growing from the requirement. If you find yourself writing duplicate code, you refactor to eliminate it, even (perhaps) adding an abstract class, or making a subclass, etc. You and your co-programmers always keep the code clean.
You're building a class, and suddenly you get an idea for a feature you could add to it. You don't need it right now, but "Someday we're gonna need ...", you say to yourself.
Keep in mind that you are employing other ExtremeProgramming
practices that allow you to deal with the future when it happens. CollectiveCodeOwnership
allows you to change anybody else's code to give it the functionality you want. RefactorMercilessly
make it easier to understand the best way to add your functionality. UnitTest
s help ensure that your added functionality won't break any past functionality. So if you do need to implement this feature in the future, it probably won't be much harder than it would be to implement now.
At this moment, you have a choice: continue working on what you signed up to do, or begin working on something you didn't sign up to do, and that isn't needed in this Iteration.
Therefore, tell yourself YouArentGonnaNeedIt
. Set aside your thoughts and fears about tomorrow and get back to work on today. Without a clear use for the feature, you don't know enough about what is really needed. Spending time on it is speculative at best.
How serious are we about this? Here's how serious: if a developer finds a method in the system that is not sent, she should remove it. Ditto unused classes, in spades.
The upside in a nutshell: it keeps the system small and understandable.
The downside would seem to be that it may take longer in the future to do something that would have taken less time now. This turns out not to be the case. It has never happened in two years on the C3 project that we wish we had added functionality we didn't need at the time. There's something of the self-fulfilling prophecy about this argument. I've been trying to persuade myself to adopt YAGNI more rigorously for several years, but I haven't managed it yet. As a result, I occasionally come across cases where I think I'm glad I didn't. On the other hand, if you've gone bankrupt implementing features you didn't actually need, you'll self-fulfill in the other direction.
Replacement/paraphrase of deleted comment: "Ummm...but the C3 project didn't turn out so well, as I understand it, so how well does it really serve as an anecdote?"
That depends on whether or not CthreeProjectTerminated due to a lack of unforeseen future functionality and if WasChryslerComprehensiveCompensationSuccess even though it was terminated early.
There are, on the other hand, places where the system isn't what it ought to be. These are mostly due to these causes:
- Use of a framework that's bigger than the actual problem we have;
- Over-engineering, resulting in classes that are too complex but hard to refactor down to reasonable;
- Delay in refactoring something that needed it.
, therefore, cases where we wish we had done better engineering of what we had ... but not cases where we wish we had put in things to be used later.
Contributors: KielHodges RonJeffries
and many many others
has generated many related pages. If you have comments or questions about YAGNI, please consider using one of the pages below rather than adding new comments to this page.
You might or might not need it:
- YouAreGonnaNeedIt, YouMightNeedIt, YouReallyArentGonnaNeedThis, WhenAreWeGonnaNeedIt, DavesRealExampleWhereThinkingAheadWouldHaveHelped, YagniExceptions
Organizational and methodological issues:
- OaooBalancesYagni, EconomicsOfYagni, YagniAndCompanyAssets, YagniAndReuse, YagniAndTeamDynamics, ElicitingRequirements
YAGNI as applied to specific domains:
- YouArentGonnaNeedItAndYtwok, YagniAndLogging, NeedingBinarySearch, NotNeedingBinarySearch, YagniAndDatabases, YagniAndCpp, YagniAndCostOfChange
Pages with related philosophies:
- DoTheSimplestThingThatCouldPossiblyWork, JustSufficientImplementation, PrematureGeneralization, JustInTimeProgramming, ForthValues
- ExtremeNeed, RefactoringYagni?, YagniIsBologna, DoesYagniInterruptFlow, YagniAndDeleting, DecisionMathAndYagni
Traditionally, ordering your implementation efforts has been done by subsystem - you implement everything in a subsystem's interface, and then move on to implementing the next subsystem, and that makes for a lot of useless overhead with a BigBang
at the end where you do all your testing and QA. YouArentGonnaNeedIt
is suited to an iterative or evolutionary development method whereby you do a fair amount of planning and architecture definition up front, and then implement by feature-set rather than by subsystem.
As I just wrote in ShieldPattern
, I think this is an example of a force, not a pattern. There are circumstances where premature work would be wasted. There are also circumstances where a little bit of forethought and planning has saved me enormous effort further down the line. The best way to balance conflicting forces may not be to yield to one of them. (PS. I think identifying forces, and their strengths, is a valuable contribution - see PatternComponent
I suggest that the forces are the cost of investing now, vs savings then, or something like that. The pattern would be "Do it now" or "Do it later", perhaps?
Not only might you not need it in the future - even if you do, it might not take the exact form then, that you can anticipate now. Also, how are you going to test it, if you don't need it now?
The one exception that I would make to this is consistency with standards. For example, if I have a standard that I always provide a getter for any setter, I will add it immediately, even if I don't need it now, lest someone trying to maintain the class later assume that I really intended the attribute to be write-only.
- I don't always provide getters for setters. I'd say your second paragraph here should be in the opposing column, because it advocates writing stuff you don't need. -- DaveHarris
- I would first take a careful look at any code that requires a "setter." Directly changing a class variable is a strong hint you have an encapsulation problem.
I've been meaning to say this for a while. Here goes. I think that much of the conversation that we have been having about ExtremeProgramming
practices, and many of the contentions, have been because of PrematureGeneralization
. Not in code, but in concepts. YouArentGonnaNeedIt
has spawned an incredible number of subpages and back and forth discussions. I'm now convinced that this is because the words YouArentGonnaNeedIt
themselves have no context. At first glance, that is without reading further and looking at Ron's page and much of the discussion
, the words can be used to justify just about any form of avoidance right down to hacking.
That said, I understand what is intended by the words YouArentGonnaNeedIt
, but it is only through context and example. The words themselves are aphorism that can be taken to be very general. I am excited about ExtremeProgramming
and I hope that descriptions are published, but I also hope that enough context is published to prevent misunderstanding. -- MichaelFeathers
This is an interesting and important point, IMO. Kent and I both like strong statements, memorable phrases. "ExtremeProgramming" for example. To try to learn what a pattern is from its name, however evocative, is perilous. ExtremeProgramming and YouArentGonnaNeedIt aren't even patterns yet, they are characterizations of a philosophy that is undergoing change and testing every day. We XPers may be generalizing prematurely in thinking we know what we are doing: our readers are certainly generalizing prematurely if they assume that a phrase like YouArentGonnaNeedIt justifies hacking or writing only half a function. Thanks for putting this idea so clearly. Rewrote the lead-in in response. -- RonJeffries
Twice, in different organizations that practiced traditional CodeOwnership
, I've seen situations where a developer got ahead of the rest of the team, and, rather than helping the team catch up, spent time making their yet-to-be-used code "reusable," adding features that would certainly
be needed. But by the time the team caught up, more was known about the problem, requirements had drifted, the design had changed, etc.
But there sat the developer with the work of art into which he'd poured all of his talents, unwilling
to acknowledge that it wasn't quite what the rest of the team needed after all, and resisting requests for changes. -- DaveSmith
- Agreed. I don't think anyone is advocating this. -- DaveHarris
can be a triple whammy:
- time that could have been spent helping the team reach a milestone is lost
- the code base gets bloated
- enflamed egos weaken the team.
Better to build what you need as you need it, avoiding unused clutter, and discovering and harvesting reusable components as you go.
The "did you finish high priority task X?", "No, but I wrote this neat new feature" conversation doesn't just happen between programmer and PMs. More than a few times as a programmer I've had to prod my fellow coders to complete work I'm dependent on for my progress. As much as I might like to do mine and my co-workers tasks, I've never found that conducive to meeting schedules. -- StevenNewton
In the large C and C++ projects I've worked on, the implied message is often "we don't want to touch
that part again," since touching often means recompiling, and touching the lower levels may imply rebuilding most or all of the product. The fear I perceive in my co-workers is that if you don't do the lower levels right the first time, you're going to spend 60+% of your time just waiting for the product to build.
is a lot easier in Smalltalk than it is in C++. -- DaveSmith
Change can be difficult when the tools don't support it. When it's possible you should choose your tools and processes to make change easy, but you don't always have that luxury, and the practices must bend accordingly. Nonetheless, all things being equal, a process that invests less in unnecessary futures will have more to spend on necessary presents (for the staff). The question becomes: what's necessary.
You can refactor C++, but it takes focus. The less people are allowed to refactor, the more the "get it right" fear takes hold. But if you have comprehensive unit tests for every part of the system, and you work hard all the time to reduce the compile time impact of changes - tightening up use of forward declarations, narrowing the interfaces between different packages - you can make it easier to have highly changeable C++.
People can refactor in C++. The perception that it's hard to do so is most of the problem.
And how large does a system have to be before you can't build it every day anyway?
If I was applying YouArentGonnaNeedIt
while I was implementing #isLeapYear in Date, and I knew, from previous difficult experience, about all the various flavors of leap years, and I was acting as a moral developer (or if I was tempted not to, at least my partner was acting moral), then
I would implement UnitTest
s representing all the interesting problems I knew about and I wouldn't be done with the EngineeringTask
until they worked. If I didn't know about such problem, but I suspected them, I would do the necessary research before starting.
is not the same as forgetting experience, acting stupid, or abandoning morals. It is a challenge to developers to abandon their fears of a far-flung future that may never happen and do an absolutely stellar job of solving today's problems today. Actually, when I violate this rule, it is typically because I am overwhelmed by my fears of not being good enough for today's task. Solving tomorrow's problem is an excellent avoidance strategy, because you can't be proven wrong.
-- KentBeck BeBraveLittlePiglet
A consistent thread here is that there are two different time periods, now
. The anti-YAGNI folks seem to believe that in now
, there is enough time to implement the needed features plus extra time to add possibly-desired future features (including generality and flexibility). This is good thing, because later
there won't be enough time to add the newly-needed features, and only the efficient use of the extra now
time allows later
work to be successful.
If this is true, then what happens when it's even later
? Does the project collapse under it's own weight? Does there need to be more time spent now
to plan for the features needed even later
(since there certainly isn't extra time later
The YAGNI rebuttal is that since there will always be an even later
, treat now
the same as later
by doing now's
. -- JeremyCromwell
At times, I've seen the idea of leaving extra unused fields in data structures to be useful for expansion and backward compatibility. I'm not sure how to reconcile it with ExtremeProgramming
, but in my experience it can work. Of course, empty space is not functionality.
When I have an "inspiration" to add a method to a class that isn't needed right away, I create it, but the body just throws an exception. That way I "save" the idea, don't spend the time writing the method, and it's easily caught in testing when it _is_ used.
Kind of like eating carrots when you really want a smoke. On C3, we would have to build a special convention. One of the ways we remind ourselves YouArentGonnaNeedIt is that all engineers routinely remove methods that have no senders. -- RonJeffries
... Bit aggressive that: do you dispense with backing up if you don't have a crash for a while too? :-o -- AndrewCates
I think the principle applied to backups is "Don't do them until you need them", where "you need them" equates to "you are storing important data" rather than "you have crashed" - JohnJamesIrvine
- I think that YAGNI applied to backups would be: "Don't start doing backups until you have crashed". And no, I wouldn't seriously advocate that either. (But when do you first need it?) Nothing about YAGNI calls upon the removal of function that was added when it was needed: that would be YouNoLongerNeedIt?.
- I find that some XP practices, notably Yagni and OnceAndOnlyOnce, are supposed to only really apply to the code. With code, it's easy to add stuff when you need it (or at least no harder). In the physical world, the cost of change is usually much higher. This is why we have backups, insurance, and fire-proof safes. It is also why many xp practices seem silly if you think about them with a physical metaphor.
I tend to use comments for the same purpose, though the 'method that throws an exception' idea seems useful. If YAGNI, but you know _now_ how to do it, why not install the method as either an exception-thrower or a comment, and comment heavily on how to do it? Documenting thoughts, plans and possibilities doesn't take long - certainly less time than implementing and thoroughly testing - but ensures that whatever you're worried about is written down for the next person to consider.
How about an example: A client asks for a system to hold ten objects, so I write code using an array of size ten. A week later the client says that they want to add more objects on the fly. So I rebuild using a Vector (I'm programming in Java). I could've used a Vector first time 'round, but didn't because of YAGNI, and an array is by most definitions simpler. And now I've got to start from scratch. Is this a problem with YAGNI, or how I'm interpreting it?
When the client changes, amends, or further explains a requirements, some changes are to be expected. The point is to keep the roots of a change shallow to make it easy to pull out later. To guess and guess wrong about what a client's future intentions may be only grows those entwining roots deeper and make the choice even harder to rip out later.
In the example you've got, there's three sets of objects. They are the container, the objects to go into the container, and the clients to the container. The last two wouldn't have to be changed, assuming you've got decent encapsulation.
But if you choose the Vector to begin with, you might not be so careful about enforcing encapsulation. So if the customer asks you to store a list of Strings along with objects, and you have to change your container from Vector to HashMap, the change might be difficult.
The point is that the requirements are always going to change in unpredictable ways, so trying to design for that unpredictable future is a losing proposition. But you'll always need flexibility, so designing for flexibility is a winning proposition. If you have flexibility, then the cost of putting in the feature when it's actually needed shouldn't be much higher than putting it in at the start.
And is an array necessarily simpler than a container class? DoTheSimplestThingThatCouldPossiblyWork is a subjective standard and will vary somewhat individual to individual. (See WhatIsSimplest for more.)
The "simplest" thing is not a license to implement an under-designed solution to a system, particularly when your vision of the client's needs may extend beyond his own.
In other words, there is another pattern at work here: TheCustomerWillAlwaysWantMore?
. No, really. Every single time.
No, you miss the point. If you put the customer's objects into a TreeMap instead of an ArrayList, just because you thought he would eventually ask you to index them by string, you're screwing the pooch. Do what is right for right now, and write good code. That's all.
I exercise forethought when we go on a car trip. I run around grabbing everything we might need or want on the road -- food, six different things to read, umbrellas, and of course baby stuff: the stroller, some blankets, toys, two snuglis, lots of formula, one diaper per hour, a whole big package of wipes...
My wife, on the other hand, exercises more
forethought: she points out that we don't actually need most of the stuff, and that there's a lot of benefit to traveling light - we get going faster, we have room to bring stuff back with us, we don't have a bunch of stuff to bring in from the car when we get home late at night.
I wonder how she'd react to a new nickname: "Yagni". -- GeorgePaci
Perhaps, if you know
that you're going to need to do X, then adding X isn't a violation of YAGNI or DTSTTCPW.
But suppose you implement
X (needed now) and
Y (you claim (correctly) that you'll need it) and the time taken to implement
Y now takes you beyond a time limit of which you weren't aware. The project is cancelled, so you really didn't need
Y after all. What's more, if you hadn't spent the time on
Y you would have satisfied the GoldOwner/GoalDonor enough that the project would not have been cancelled.
I've worked with "balls out, get the job done quickly" programmers, and while that seems to be very YAGNI, it wasn't very Good.
That may seem to be very YAGNI but I don't think it's what the pro-YAGNI folks are talking about. YAGNI is a principle meant to be applied within the context of XP, or at the very least a set of practices that includes refactoring. As KentBeck
points out toward the top of the page, adhering to YAGNI without the pairing, unit testing and refactoring (i.e. balls out, get the job done quickly) "clearly doesn't work." -- JasonArhart Huh? Blowing off mental masturbation and avoiding issues that aren't actually pressing doesn't require XP at all. YAGNI, and the sky ain't gonna fall!
I can't help thinking that there are essentially a set of well known exceptions to YouArentGonnaNeedIt
where no experienced developer would seriously consider waiting until later on to implement a probable requirement. At the moment the only one I can can think of is internationalization. Would you really write a large financial application for a European multi-national with hard coded messages everywhere and worry about internationalization later? -- DavidPlumpton
If the client is deploying this application around the world, then you are going to need it, and it will be reflected in the UserStories
to prove it. If the client is only deploying it in one office in the US, you aren't gonna need it. In the latter case, many would (and have) argue that you should put it in anyway; YAGNI disagrees.
There's no question that i18n is difficult. The question is: Is it much more difficult if you wait to do it when you need it? If somebody gave me pre-existing software and told me to internationalize it, the first thing I would do would be search all the code for instances of text-delimiting characters like ", ', and (if your language uses "here" documents) <<. I wonder if that would take care of the problem ... -- francis
No, I think i18n is a good example of something you would want to start doing from the beginning (or not too far into development). There are many considerations to be made throughout the development. However, YAGNI still holds if the client doesn't make it a priority.
It seems to me that hard-coded constants of any kind - messages, magic numbers, whatever - are inherently inflexible and should be avoided on general principles. You can make it possible to internationalize later without taking the time to fully implement your interface in ten different languages.
I think what causes much confusion for the readers (ok, I admit it: I talk about myself here) is where to draw the line between "foresightment" and "programming unneeded features".
Hardcoding messages for the user into the code does not sound smart - but it would apply to the YAGNI rule. I know when I write a program, that with high probability there will be an point in the future when someone wants a change to a message. Be it that the program is released in another language, or just that there is an spelling error.
If you used the YAGNI rule, you would have to search through the code for every message. If you had foreseen that (from experience), and written something to make messages easily accessible, you could have saved a lot of time. Or am I wrong here?
So is foreseeing later problems always bad?
s in some way breaking the YAGNI rule? Since you write something you only need if you write bad code?
- Possible sources for an answer: EconomicsOfYagni, WhenAreWeGonnaNeedIt, YagniIsBologna, XpSimplicityRules and TestDrivenDevelopment
In XP you need Unit Tests in this iteration, because you will do continuous integration and probably also some refactoring.
From my experience trying to explain YAGNI to less XP-enlightened developers, I have come to deprecate "YAGNI", in favour of WdNiy
ProblemDomain and applicability
May I make a suggestion. I think YAGNI, like most XP policies, is a good set of ideas to keep in mind, but another is "know your problem space". YAGNI doesn't mean you should choose an array of 10 spaces over a Vector. Most programmers know that if you need two, you need many, so if you have the choice, you choose a solution with the ability to expand. [A]
My motto has always been more along the lines of: Understand the problem space to the best of your abilities including required, optional and possible requirements. Once you have done this, program so as not to preclude the optional/possible requirements wherever possible.
There are exceptions. Twos may just be binary splitting; threes are almost always manys. -- Joshua Hudson [B]
I've very recently had an AhaMoment
regarding this topic. For ages I've considered YAGNI harmful for various reasons, but what if we shift the emphasis to the YOU, as in YOU aren't gonna need it
. Suddenly, we can drop all these discussions about time as YAGNI ceases to be a statment about now
, and becomes a statement about you
. This formulation sits a lot better with me, though of course it is very open ended as to who exactly you are (developer, team, or company?). -- RichardCordova
What is the OppositeOfYagni
Would CoupleLeapingWithLooking serve the purpose?
(a good solution) because if you start out with something bad and continue to hack the bad solution (YouArentGonnaNeedIt
), it might end up worse than if you had done some thoughtful design first.
(HdykYagniE) and SoYouReallyThinkYourArentGonnaNeedItHa?
Yagni is often applied as a principle to justify failure (hesitation, decision) to partition or to separate fully (see PrinciplesOfObjectOrientedDesign
are applicable as principles to counter such justification. I suppose that such a counter could get into even more questionable principles such as ButWeHaveNeverNeededItBefore?
All of this may have more to do with OrganizationalPsychology?
(Carl R Castro)
Several people on this page have mentioned something I believe to be key to understanding YAGNI. Every programmer makes judgment calls all the time about whether to invest now for the future, or delay work to the future. The programmer must evaluate the costs of implementing more general and reusable code vs the cost of doing that more powerful implementation. It's the simple standard question of investment, which every programmer does on a daily basis. These things play out when deciding if you should invest in code:
1- What's the cost of the investment, of writing the "better" code now?
2- What's the cost of delaying? AKA How much harder would it be to write later vs now?
3- What's the likelihood of the investment being used, and how much value would having this investment be?
4- What is your time horizon? Do we need something now, and the future is less important? This is a very normative question which depends on the company, share holders, etc.
5- Opportunity cost. Could your time be better spent elsewhere?
YAGNI is simply an observation that many people do not base their designs on cost benefit analysis. They program for fun, for academic reasons, etc., and not for the company's bottom line, and this is a very bad kind of programmer to have in a company.
For example: the aforementioned case of using Java built-in array vs Java Vector. It's a simple decision. There is no cost to invest in the better implementation, the implementation using Java Vector, thus you should invest. You may or may not use the more powerful aspects of a dynamically resizing container, but you lose nothing by using Vector over an array.
However, you might have a case where you need to decide between single threaded, multi threaded, or distributed. There are definite costs in implementing the "better" system over the simpler system, so you need to do the proper cost benefit analysis as outlined above in order to reach a reasonable conclusion.
As a vague claim unsupported by facts, I tend to believe that a little
investment up front for a cleaner design almost always pays off in the end. Not very YAGNI I know. However, in my current company, I see many many places where I wish people did practice YAGNI, instead of producing overcomplicated designs that are a pain to debug, enhance, and maintain.