17 ms·
Yagni
- beat 11y agoAs always, it's a joy to read Martin Fowler. It's so, so hard to resist the siren song of premature optimization, though. It's even harder in a corporate environment where "Well, why didn't you plan for that?" is a question lurking behind every failure or delay. Overplanning isn't punished.
- mkozlows 11y agoThis is becoming less true over time. As enterprises start adopting Lean practices, it becomes obvious to everyone why building something now when you won't use it for months is waste.
- beat 11y agoIf there's one thing enterprises don't give a flying fsck about, it's waste. After a couple decades of mostly-enterprise development, I've learned something really important - it's better to not be wrong than to be right. Thus the overbuilding and risk aversion. Frankly, this is the only real advantage startups have over the enterprise - the ability to take risk.
- mgkimsal 11y ago"it's better to not be wrong than to be right" My limited experience in that world was that there often wasn't a really good way of identifying when something was in fact 'right', only that it wasn't broken (whenever it was reviewed/inspected). New info could always come along which would call in to question previous decisions, and new people would come in with different (or no) understanding of previous stages. Couple that with organizations in which everyone is free to say 'no' to things, or they're free to chime in with demands without having to actually commit resources for dev or support, and you get weird situations (I've got a few war stories, as I'm sure many people here do too).
- briandear 11y agoI disagree. If overbuilding or over planning is wrong. Then the question comes as to why you spent $200k building a feature that just got thrown out. Or worse, they try to use a unneeded feature just to justify the fact that it was built.
- beat 11y agoI didn't say it isn't wrong. I said it isn't punished. That's a very, very different thing. Enterprise environments encourage toxic behavior in numerous ways. This is one of them. Risk aversion is generally more important than cost control in the enterprise. Conway's Law in action, if you think about it.
- not_with_retard 11y agoBecause if you didn't spend 200k then actually came to need it, you would have lost your 100 million dollar deal. It's a completely different beast, and making sure your ass is always covered is of utmost importance, which is why the largest companies are constantly doing it. On a much smaller scale, and hopefully one more relatable, this is why even smaller businesses always go with the software/hardware package which includes support. Cover your ass.
- pbreit 11y agoIn startups, overplanning is punished by company failure.
- Silhouette 11y agoIn startups, almost everything is punished by company failure. Another example is failing to plan ahead far enough that you can maintain your first mover advantage when a competitor comes along and already has the benefit of learning from your mistakes so far.
- endymi0n 11y agoWe have one rule when planning product features: Everyone may shout YAGNI at every time. Saved us so much time and complexity, it's incredible. On the other hand, I have a love/hate relationship with YAGNI, as it requires careful weighing - additional features that need to be reflected in architectural changes which would not only take refactoring code but API and data model changes as well, possibly with data migrations, coordinated across multiple teams are a completely different picture. The costs of building it now may be an order of magnitude cheaper than doing it later. Further down the road, startup mechanics and traction apply as well. If you have an order of magnitude more resources to fix YAGNI later, it might be worth the additional speed right now. I feel that putting all of these into context and doing something that makes sense is just freaking hard every single time.
- angersock 11y agoYagni only applies to capabilities built into the software to support a presumptive feature, it does not apply to effort to make the software easier to modify. And here is where the actual frontlines of the battle are fought--because it's needlessly verbose and abstract architectures (or what people think are them, anyways) that are railed against by folks chanting "yagni yagni yagni". This article neatly sidesteps the actual thorny issue of "well, when is designing extra actual a good idea?" by ignoring one of the biggest use-cases of yagni.
- wrsh07 11y agoAgreed -- the article cleanly argues for Yagni by moving the heart of the discussion to a bolded sentence near the end.
- oinksoft 11y agoThis is just my experience, but "YAGNI" is often shorthand for "I don't want to think about it." I'm not talking about criticisms of wasteful design/features, but somebody actually saying "YAGNI" with little elaboration. It's imprecise and lazy.
- angersock 11y agoYep. I especially hate hearing it from well-meaning folks who, say, bring it up whenever talking about architecture decisions and devops stuff, but apparently see no reason not to spend one or two weeks fiddling around making The World's Best Angular Form Field Input Directive, or painstakingly tweaking the secondary and tertiary colors in their alert boxes or some damn fool thing. EDIT: At this point, especially in the web, I'm now considering Diarrhea Driven Development: shit out as much as fast as you can and make it as viral and sticky as possible.
- apalmer 11y agoI hear you, I think this article is really good for someone who isn't familiar with the term YAGNI. However as the above poster mentioned it sidesteps a big issue which is when YAGNI is wrong. Generally I feel like YAGNI is appropriate for features but not appropriate for architecture. I feel like the purpose of architecture is to try to plan ahead, or to make the determination how far ahead one is attempting to plan. Its perfectly find to architecturally choose not to support something, but it should be a conscious decision.
- webtards 11y agoI think the ability to use YAGNI scales with the experience and abilities of the developer and the team. I have walked into wonderful lean codebases where an experienced hand has kept featuritus down to a minimum, but I have also walked into codebases where multiple kitchen sinks were not only present and plumbed in, but a pile of new ones were ready and waiting by the side to join them, and it was a massive distraction.
- eridius 11y agoSomething this article largely ignores is that often you want to build the support for the presumptive feature now because the act of implementing it affects architectural decisions. It came close to this by saying > it does not apply to effort to make the software easier to modify But there's a difference between making software easier to modify (where the same effort could be expended later to retrofit the software) versus making architectural decisions. Often times trying to implement something teaches you that your architecture isn't sufficient and you need to change it. If you can learn that while you're building the original architecture, then you've avoided a potential huge amount of work later trying to retrofit it. To use the example from the article, what if supporting piracy risks reveals that the fundamental design used for representing pricing decisions isn't sufficient to model the piracy risks, and the whole thing needs to be reimplemented? If you can learn this while implementing the pricing in the first place, then you haven't lost any time reimplementing. But if you defer the piracy risks by 4 months, and then discover that your pricing model needs to be re-done, now you need to throw away your previous work and start over, and now your 2-month feature is going to take 3 or 4 months instead.
- pimlottc 11y agoBut on the gripping hand, deferring an implementation often means you understand the problem better by the time you get to it, so that your actual implementation is better than the naïve version you would have written earlier.
- eridius 11y agoFair point. Making these decisions correctly is hard. I'm pretty sure this is one of the things that you slowly learn how to do with experience, that no amount of being smart or research can make up for.
- Spearchucker 11y agoI think you had it right first time. Much like you can define an interface without a concrete implementation, or a unit test without working code. One rather hypothetical approach to the problem is separation of concerns - make pricing composable - starting with storm risks, and supporting other unknown, future risks. The obvious follow-on I see too often is to use some type of dependency injection, which is almost always (my experience - YMMV) a bad move - pricing risk components probably don't change often enough to warrant the configuration nightmare that ensues. Just recompile, and redeploy. Or use reflection to load available pricing modules, assuming the perf hit is acceptable. You may not need to know the intricacies of pirate risk when delivering storm risk, but you do know that you'll be dealing with another risk after delivering storm risk. So plan for it.
- jmadsen 11y agoI think it is important to differentiate between "early building" of features you don't yet need, and building in a way that doesn't require much refactoring in order to extend/add those features on. More common than overbuilding features is overbuilding function or library capability. The right balance, IMHO, is _thinking_ about the extendability & designing for it but leaving out the actual details. This tends to lead toward good, SOLID designs that are easy to work with later rather than a blind-ally you need to spaghetti-mofongorate to get to work. "Refactor later" is fine for folks like Martin Fowler who know _how_, and who haven't painted themselves into a corner with bad early decisions. It is a bit dodgy to tell the average mid-level dev who just wants to "get it done" so his Project Manager can check off their Excel spreadsheet that they are on time.
- deleted 11y ago[deleted]
- moron4hire 11y agoExtensibility is itself a feature, so YAGNI would imply it shouldn't be assumed until proven necessary. I personally use the "zero, one, many" rule (i.e. those are the only counts of things, there is no such thing as 2 or 3, etc.) as my proof of necessity. If I ever get to the point that I need two of something, I make it useful for many of something.
- beat 11y agoI've found that designing for extensibility is wrong more often than right. The code doesn't stretch the way you expect, and then it strains against other boundaries you didn't realize you were setting.
- jmadsen 11y agothat's not quite what I mean. saying, "I think it will need feature X, which will require parameter x_id, so I'll add x_id = 0 now" is wrong. writing (just as an example) a function that takes an config array as its param so you can later build out, instead of passing a_id, b_id, c_id...."oh, crap, how long a list will this be?" in the early build is the type of thing I mean. Writing extensible code more often than not causes you to write smaller, tighter, more testable components. Writing in this style is what I'm trying to say. Many less experienced devs would not do this and end up with long procedural code because they feel it is wasted time for something they aren't anticipating.
- chris_va 11y agoI think this is trying to simplify an already simple idea, succinctly: "Optimize your time intelligently". Rules of thumb (like YAGNI) may not be correct, depending on the situation. Estimating time complexity is hard, so deferring development defers mistakes in estimation. Great. However, if you know that you have a 90% chance of needing a feature in 6 months, and it will be 2x easier to build now when you have a team actively engaged on a similar project, then YAGNI is the wrong choice. Counter examples exist, like you are in such an extreme environment where (like first month of a startup) the opportunity cost of those programmers is very high. Regardless, I would ask "Is this the best use of time now" rather than "YAGNI".
- pbreit 11y agoThe whole point of the article is that you're wrong. And I tend to agree. Not trying to predict feature needs down the road is extremely empowering. Building you're unnecessary feature now is just as likely to increase the complexity of everything in the future as it is to be 2x easier to build now. YAGNI dramatically simplifies the answering of your question: if it's not needed now, don't do it.
- chris_va 11y agoUsing your example: Let's say I know it will cause a complexity burden in the future. Shouldn't we ask if that complexity burden and opportunity cost are outweighed by the expected benefits, rather than rather than simply relying on a simplistic rule of thumb of always deferring? People are capable of (which, to your point is not the same as being consistently good at) making good calculations as to what is a waste of time.
- pbreit 11y agoQuite a contrived scenario, but, no. Just build the feature you need and move on. No need over-analyzing. See? I didn't have to get trapped in your pretty much un-answerable pondering. Following the rule crystallizes a lot of decision-making. It's very empowering when you don't have too many objectors.
- jonahx 11y agoThese days, I think "Yagni" is often used as an excuse for sloppy code and as a justification to avoid thinking about design. I think the principle as Fowler describes it is valuable, but it can be easily abused. Taking the application of "Yagni" at the microlevel to its logical conclusion can be used to justify a mindless, just move on it and fix it later style of coding into which good architecture cannot be retrofit.
- esfandia 11y agoYAY (Yagni Ain't Yolo)?
- lmm 11y agoI have yet to see up-front "architecture" add value, and I have seen it sink a company.
- robmcm 11y agoWorking on software with 10s of developers it is vital.
- lmm 11y agoNot my experience at all.
- jonahx 11y agoHi lmm, perhaps the world "architecture" has bad associations for you that I don't intend to imply. If you code anything non-trivial, you are doing architecture whether you like it or not. The only question is how well you do it. Over-engineering is a real danger, to be sure, and terrible ideas can by justified in the name of "architecture," just as they can in the name of YAGNI. Fwiw, I have personally seen costly decisions made in the name of YAGNI, literally. So I don't think it is the essentially "safer" default. My view is that you can't always wish away complexity with heuristics. Often, you have to think through your special situation, weigh the factors, and make tough judgment calls without knowing if they'll be right.
- pbreit 11y agoI love how these types of articles always bring out the architecture astronauts with all their pronouncements of "it depends" and whatnot. How hard is it to understand the notion of "building what you need, and not what you don't"?
- asgard1024 11y ago> How hard is it to understand the notion of "building what you need, and not what you don't"? Very hard, because it's in fact a tradeoff. Let's say you are building a house. Will you have wife and kids in the future? YAGNI says you can always expand your house once you have kids. But do people really build houses that way? To take more extreme example, first thing you expect from housing is a protection from elements. So according to YAGNI, you should build the roof first, and see if it's good enough for you (and you don't bother, for instance, that you can only stand in the middle of the room). Again, no one really does that with real houses. The whole art of engineering is to pick the reasonable tradeoffs, and this includes hedging against the risk of future expansion. That's why simple pronouncements as YAGNI are not of much help.
- lmm 11y ago> To take more extreme example, first thing you expect from housing is a protection from elements. So according to YAGNI, you should build the roof first, and see if it's good enough for you (and you don't bother, for instance, that you can only stand in the middle of the room). Again, no one really does that with real houses. Maybe they should. I once stayed in a house with no internal walls. It seemed weird at first, but then I realized I actually quite liked it.
- pbreit 11y agoExtreme examples are not that interesting (to me) since it's far more important to optimize what is not extreme. A better house example is to go ahead and build the 2-4 BR house (like pretty much everyone does) but wait on the pool and jungle gym.
- asgard1024 11y ago
- deleted 11y ago[deleted]
- addisonj 11y agoThese comments seem to illustrate something I have felt for a while: yagni is incredibly divisive topic and for every person saying praising it is another who is at the very least cautious of its application. It makes me wonder where the divide is. Perhaps more large 'enterprise' shops where projects can spin out of control into what they 'must have' whereas the small shops where you need to get a product out ASAP? Or maybe age of developer, with the young eager guy confident he can whip out all n features in 3 weeks so we might as well add that feature too vs the experienced dev who knows better and we will add it once it is needed? I have put some time and effort into asking people about this very question, but still am no closer to understanding why some really appreciate it and others hate the phrase. Personally, my guiding principle after being bit by yagni is that it is a wonderful principle to use when making product/feature decisions but should be exercised very carefully when making architecture decisions. Which makes sense, features come on and go, but architecture is generally something you need to live with. In other words, whenever yagni is used is an argument against what are more good coding and design practices than practical problems, then it may be something more of a case of 'no really, we are going to need it'
- TillE 11y ago> It makes me wonder where the divide is. I think it works beautifully if you're applying it along with "refactor mercilessly", backed by good unit tests. It's a principle that doesn't necessarily stand on its own; it needs to be part of a healthy, iterative system of development. If refactoring becomes difficult or dangerous for whatever reason (eg, designing an API for long-term, widespread usage), then YAGNI may not work.
- mtVessel 11y agoFunny, I think of the age divide running the other way. Younger devs, who came up during the age of agile, take YAGNI as a given, while older devs have seen the results of too many hasty decisions. The advice I was given when I started out was, "it's cheaper to fix something upstream". Catching a potential problem during design is always cheaper than catching it during development, which is cheaper again than catching it after release. This argument always seems to get lost in the YAGNI discussion.
- 11y ago
- rsp1984 11y agoIn my years of experience (both in big corporate R&D as well as startups) I've never seen a project fail because of the end product being too simple or not having enough features. However on the other hand I've seen countless projects suffering delays, staff departures, emotional team arguments and eventually bad end product because of too complicated software architecture that overwhelmed its creators and because of obscure features that well-meaning engineers built in because "it'll save time in the long run". Btw this well known XKCD sums it up just perfectly: http://xkcd.com/974/ http://xkcd.com/974/
- krupan 11y agoI dealt with this recently. We wrote a system that had a hard-coded data size in it. Later, that data size had to change to a flexible value chosen on the fly, and I was the one that had to go through all the code to make all the changes so we could handle that. It took a long time. Partly because we had no unit tests (a whole 'nother discussion), partly because I wasn't familiar with the area (all the areas) of the code that needed to change, and partly because we had said, "YAGNI" and not made our code configurable enough from the get go. I started to curse YAGNI in the middle of that chore, but then I paused and thought about the many months of productive use of this code that we had been enjoying before this point. And even though it took me significant time to make that change, the production code was still running along just fine during all that time, still bringing us value. I decided that I was glad we had said, "YAGNI" at the start.
- mbell 11y ago> Partly because we had no unit tests (a whole 'nother discussion) I think that the is the primary point. If you have good test coverage at each level, it's actually really easy to make large sweeping changes to a codebase. If you don't have those tests, it's hell. This is a big part of why I think unit tests are ok, but not nearly as important as good E2E and perf tests, as painful as they can be to write and wait for to run some times. Good high level tests let you tear the heart out of the codebase, replace it and still be confident it works.
- shoo 11y agoI agree that having good test coverage across different levels/purposes makes sweeping changes far quicker, easier, and even feasible to consider doing. Building and shipping the software is perhaps half the work - another half of the work is growing and maintaining the scaffolding to rapidly, automatically and reliably measure the properties of the software that you wish it to have. It seems no-one here is arguing that YAGNI should be applied to justify not building automated tests.
- krupan 11y agoThe one thing we did have was good end-to-end tests. When they failed, it was the unit tests I was wishing for.
- lowbloodsugar 11y agoI used to play Age of Empires. Its a real time strategy game where a common match is for two teams of three to try to kill each other. A feature of the game is that each player can spend resources (gold, wood, etc) to reach new "ages". Players start in the stone age, and advance to tool, bronze and iron ages. Each new age offers better weapons, better technology, greater efficiency. Consider two games. In the first game, we observe that the players take on average 30 minutes to get to tool age, and only one player ever makes it to iron age before a team is victorious after about two hours. In a second game, we observe that the players average ten minutes to bronze age and all but one player makes it to iron age before the game is won after about an hour. All players invest in technology before fighting. Who are the better players?
- pdpi 11y agoI can only assume that the point you're trying to make is that there's not nearly enough information for a reasonable answer. It's certainly hard to come up with solid ideas without a clear understanding of the game's pacing. In RTS games, teching and building armies compete for resources, so I'd hazard guessing that Game 1 happens because somebody opted for early aggression, which forces everybody to spend money on units to fight off the early threat. Looks like a well balanced game where both teams kept the aggression level high, which justifies the long duration, and the low-tech end-game. Second game looks like there was little to no early-game aggression, which meant that everybody got to funnel resources into teching up early. I'm not sure if late-tech battles are more all-or-nothing, or whether one team was just clearly stronger than the other -- though if that's the case, why didn't they push for an advantage earlier? AoE is much more symmetrical than, say, Starcraft IIRC, so one team having a weaker early game but a stronger late game doesn't seem likely. I'm curious, though: how does this relate to the article?
- lowbloodsugar 11y agoThank you for biting =) The players in the first game are likely experts and if a team from the first game plays against a team from the second, the game will be over in less than ten minutes. Its not merely that "someone opted for early aggression", its that when playing at the elite level all players opt for aggression. Its not rock, paper, scissors. Its a game of rock, paper. The point is that deployed features trump undeployed "it'll be great when its ready" technology. I'm happy for my competitors to opt for spending money attempting to achieve "good architecture" over "working code". Ok, so the analogy is kind of shitty. Unlike Age of Empires, spending money on "good architecture" is actually less effective at creating good architecture than writing working code.
- bsder 11y agoExcept that Fowler used YAGNI to produce the "Chrysler Comprehensive Compensation System" that FAILED MISERABLY. I still don't understand why people continue to listen to him--he has yet to demonstrate a large project he was in charge of that succeeded. YAGNI gets you the easy 80%. The problem is that YAGNI means you didn't prepare for the hard 20%, and now you're going to get killed. Of course, YAGNI is really good if you're an ambitious manager since you'll be gone when the 20% comes home to roost.
- necrodawg 11y agoSuch failures are more often because of bad developers than anything else. It's not really fair to blame a single person on a big project with lots of people on it.
- bsder 11y agoExcept that he is preaching the exact opposite. He is preaching "Follow my religion and your project will succeed! Pay me money to teach you." Given that, it is entirely fair to blame him and his system for the failure. Just so you know: I do agree with you that big projects rarely fail because of a single person. But Fowler pisses me off because he preaches his religion with zero empirical evidence it is any better than anything else.
- necrodawg 11y agoTotally agree :)
- pbowyer 11y ago> But Fowler pisses me off because he preaches his religion with zero empirical evidence it is any better than anything else. And people take it as truth rather than opinion. Look at the way he was all-out in favour of microservices, then backpeddled recently. It's right for a clever man to think out loud and change his mind; but not for people to act on it as if it's fact.
- lmm 11y ago
- anigbrowl 11y agoThere's an extensive literature on opportunity costs in economics, but you wouldn't know it from reading this article, even though that's basically what it's about. Discussions of programming methodology often seem to involve reinvention of the wheel. Has there been any work done to quantify these theories?
- phamilton 11y agoI'm always a bit surprised when we treat "cost" as something binary. Successful people, in my experience, are those who take calculated risks and are right often enough to differentiate themselves. Software is no different. When faced with a YAGNI situation, you need to make a judgement call. There will be costs in building it now. Those costs might be less now vs later (sometimes just because the context is fresh). The cost may vary depending on how much work you do. There will also be "expected benefits". The estimated (judgement call) likelihood of actually needing it times the cost savings (future cost - current cost). Compare the expected benefits between projects and pick the one you expect to add the most value. As pointed out by others, this often means simply drawing the abstraction in the right spot to make future development easier. Even if future development never happens, it's likely you built a good abstraction that was well thought out. The cost is low (you had to frame the abstraction somewhere) and the expected benefits are high.
- mc808 11y agoOther than the navy wiping out all the pirates, I foresee a couple of other unforeseen scenarios: 1. Within the next few months, a new risk emerges with higher priority than piracy. Implementing this feature will delay the piracy addition, but only by 1 month because much of the basic "support multiple risks" problem will be solved by this other feature. 2. Within the next few months, a new product or tool will become available/known that makes it trivial to support storms, piracy, and a dozen other risks, making this whole effort redundant. It may be impossible to migrate to the superior alternative if all the resources are already tied up in a half-finished project that has generated no benefits to date.
- robmcm 11y agoThe use case in these discussions is never about framework or shared code. Taking the example of the lookup tables for error messages, imagine if you shipped your framework and lots of teams started using it, then you iterate to change your APIs in a breaking way and suddenly the cost of that change is multiplied by all the teams refactoring. It is also worth considering the cost of changing existing production code, this is typically where most bugs are introduced, especially when someone else is implementing the fix without the domain knowledge of the original author. Unit tests won't help if they also have to be re-written to match the new API, as they are by definition new/different tests. I think writing malleable code is the key takeaway from this article, and if thinking about future possibilities helps with this, then it should be encouraged. Being unable to predict the future doesn't mean you shouldn't anticipate and prepare for change.