why YAGNI acts to EXPLOIT the bottleneck

Clarke asked me to explain my earlier throw-away remark that YAGNI forms part of the EXPLOIT step in moving the bottleneck away from development, so here goes…

YAGNI (You Aren’t Gonna Need It) is an exhortation from the early days of XP. It has been discussed and misunderstood a great deal, so I’m not going to get into the finesses of meaning here. For our purposes, it reminds the developer not to work on features or generalisations that may be needed, telling him instead to focus his present efforts on delivering only what he knows is the current requirement. (In the interests of brevity, I’ll refer below to YAGNI only in terms of added behaviour, and I’ll use the word “feature” for any fragment of any kind of behaviour; all other forms of YAGNI are assumed.)

(In my practice I use a similarly attention-grabbing soundbite. Whenever I see a developer do something “because it may be needed in the future” I accuse him of crystal ball gazing. I remind the whole team that it can be risky and dangerous to get your balls out, and that seems to help the message stick. Other times there’s an embarrassed silence.)

Writing crystal ball code has three effects: In the present moment, it means that the developer is spending current time investing in one of many possible futures; in the period from now until that possible future, it means that there is code in the system that doesn’t need to be there; and when the future arrives, it may look different than that which the developer predicted.

First, then, crystal ball code uses up current development time. This is bad when development is the bottleneck and when batch sizes are relatively small and when development order has been defined in terms of business value and when feature cycle time is a KPI. The time spent developing a crystal ball feature will delay the current batch and all batches upto the imagined future. There is a tiny chance that development of that future batch will be faster (see below), but all interim ROI (for example) will be reduced by the delay introduced right now.

Second, the crystal ball code represents inventory, and it has a carrying cost. This code, which may never be required by the end user, must always build, integrate and pass all tests; if ever it doesn’t, time must be spent fixing it. Furthermore, a larger codebase will always require more time and effort to understand and navigate (think of having to drive around piles of inventory in order to fetch anything or the lean practice of 5S). Even if the guess turns out to be correct, the additional carrying cost of this inventory will slow down the development of all batches of features between now and the imagined future.

Third, the developer’s guess may be just plain wrong. Either the imagined “requirement” is never requested, or it is requested and by that time the codebase is radically different from what it is now. The developer may have to spend time removing the feature (for instance if it would confuse or endanger the user) or completely re-design it to make it match how reality turned out. It is assumed that the “wow, that’s exactly what we needed” outcome is sufficiently unlikely that the costs of the other outcomes dominate.

So YAGNI is based on a few core assumptions:

  • The product is to be built incrementally in batches of features
  • Each increment should be potentially shippable in terms of quality and cohesiveness
  • It is hard to predict what features will be requested in later batches
  • It is hard to predict what future code may look like
  • Development is the bottleneck
  • Speed of development is crucial
  • The present value of current features is higher than the future value of future features

Under these conditions, YAGNI is part of the EXPLOIT step because it helps to maximise the amount of current development effort going into delivering current value.


4 thoughts on “why YAGNI acts to EXPLOIT the bottleneck

  1. I would add one more core assumption:

    – the team always keeps the design “as good as it can be” (Agile Software Development Principles, Patterns, and Practices; page 94)

  2. Hi Alexei, I can see how good design contributes to EXPLOITing the bottleneck, because the high cohesion and low coupling help reduce “friction” while reading the code. But can you clarify why YAGNI is only meaningful when the design is “as good as it can be”? Are you implying that badly designed code prevents us applying the YAGNI rule?

  3. hi Kevin,

    After re-reading the core assumptions you’ve already mentioned, I’ve realized that “keeping the design as good as it can be” is perhaps another way of saying “each increment should be potentially shippable in terms of quality and cohesiveness”. My intention was to try to ascribe to the word quality a more specific set of principles that will serve the purpose of guiding a programmer doing OOP to produce high quality code ( in general, code that is easy to understand and change ).

    Back to your question, my answer will be yes, as badly designed code will compromise the quality and cohesiveness of the code base at the end of each increment. Ending up with code that doesn’t have good quality at the end of an increment can be seen as incurring in a technical debt. Technical debt will start accumulating as new product increments are shipped, making it harder to produce a shippable product in terms of quality and cohesiveness as time passes, and thus having a negative effect on the speed of development.

  4. Pingback: Just In Time People « Critical Results

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s