if consequences of decisions are unpredictable, henry ford said minimize decisions. facebook engineering says maximize reversible decisions.—
Kent Beck (@KentBeck) July 27, 2015
If you choose not to decide
You still have made a choice
Rush – “Free Will”
Bumper sticker philosophies (sayings that are short, pithy, attractive to some, and so lacking in nuance as to be dangerous) are pet peeves of mine. YAGNI (“You Ain’t Gonna Need It”) is right at the top of my list. I find it particularly dangerous because it contains a kernel of truth, but expressed in a manner that makes it very easy to get in trouble. This is particularly the case when it’s paired with other ones like “the simplest thing that could possibly work” and “defer decisions to the last responsible moment”.
Much has already been written (including some from me) about why it’s a bad idea to implement speculative features just because you think you might need them. The danger there is so easy to see that it’s not worth reiterating here. What some seem to miss, however, is that there is a difference in implementing something you think you might need and implementing something that you know (or should know) you will need. This is where “the simplest thing that could possibly work” can cause problems.
In his post “Yagni”, Martin Fowler detailed a scenario where there’s a temptation to implement features that are planned for the future but not yet ready to be used by customers:
Let’s imagine I’m working with a startup in Minas Tirith selling insurance for the shipping business. Their software system is broken into two main components: one for pricing, and one for sales. The dependencies are such that they can’t usefully build sales software until the relevant pricing software is completed.
At the moment, the team is working on updating the pricing component to add support for risks from storms. They know that in six months time, they will need to also support pricing for piracy risks. Since they are currently working on the pricing engine they consider building the presumptive feature  for piracy pricing now, since that way the pricing service will be complete before they start working on the sales software.
Even knowing that a feature is planned is not enough to jump the gun and implement it ahead of time. As Fowler points out, there are carrying costs and opportunity costs involved in doing so, not to mention the risk that the feature drops off the radar or its details change. That being said, there is a difference between prudently waiting to implement the feature until it’s time and ignoring it altogether:
Now we understand why yagni is important we can dig into a common confusion about yagni. Yagni 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. Yagni is only a viable strategy if the code is easy to modify, so expending effort on refactoring isn’t a violation of yagni because refactoring makes the code more malleable. Similar reasoning applies for practices like SelfTestingCode and ContinuousDelivery. These are enabling practices for evolutionary design, without them yagni turns from a beneficial practice into a curse.
In other words, while it makes sense to defer the implementation of the planned feature, it’s also smart to insure that there’s sufficient flexibility in the design so that the upcoming feature won’t cause refactoring to the extent that it’s almost a rewrite. Deferring the decision to do necessary work now is a decision to incur unnecessary rework later. Likewise, techniques implemented to ameliorate failure (circuit breakers in distributed systems, feature flags, etc.) should not be given the YAGNI treatment, even when you hope they’re never needed. The “simplest thing that could possibly work” may well be completely inadequate for the messy world the system inhabits.
If you think that programming to abstractions amounts to over-engineering, then please learn the terms "abstraction" and "over-engineering".—
☕ J. B. Rainsberger (@jbrains) June 19, 2015
It’s probably impossible to architect a system that is perfect, since the definition of perfection changes. It is possible, however, to architect systems that deal gracefully with change. That requires thought, not adherence to simplistic slogans.