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.
There are two main reasons to practise YagNi:
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?
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.
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 better than none...
||: Test me... Code me.. Refactor me... In'grate me... :|| (x8)
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)
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 and OnceAndOnlyOnce make it easier to understand the best way to add your functionality. UnitTests 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.
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.
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:
Contributors: KielHodges RonJeffries and many many others
YouArentGonnaNeedIt 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:
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?
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. -- RussellGold
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
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
YouArentGonnaNeedIt 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?
YouArentGonnaNeedIt 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 and later. 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 work now and later's work later. -- JeremyCromwell
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
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.)
Concur. 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.
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
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.
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
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.
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?
Aren't UnitTests in some way breaking the YAGNI rule? Since you write something you only need if you write bad code?
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]
Would CoupleLeapingWithLooking serve the purpose?
CategoryExtremeProgramming, CategoryDecisionMaking, CategoryJargon
This page mirrored in ExtremeProgrammingRoadmap as of April 29, 2006