Thursday, October 1, 2009

YAGNI – You ain’t gonna need it

The YAGNI principle states that programmers should not implement functionality until it is necessary.  It is a pretty simple principle but oddly enough it is a difficult principle to follow.

I’ll take a crack at what I think the upside of breaking this rule is.

  • It seems to me the biggest benefit to breaking this principle is that we can architect and design our code by taking into account both current and future features thus implementing a more robust design.
  • Another big argument is that by implementing this feature our software will be more useful.  If our software is more useful we may sell more licenses or we may be more productive.

Let’s look at the most obvious negatives of implementing a feature before you need it. This is a longer list.

  • If we don’t need it yet, maybe we should be spending our time and money implementing something we do need now.
  • If we implement a feature we should have some corresponding documentation describing the feature – this takes time.
  • If we implement something we need to test it -every release and this takes a lot of time.
  • When we add a feature in an agile/TDD shop, we need to write unit tests for the feature so we can automatically test it every release.  Writing the tests can take as long as or longer than writing the feature and anyone who has to run unit tests before a check in will probably agree that adding time to this automated process is not good.
  • When we add a feature we need to train the support crew and user base on how to use the feature.
  • A feature is hard enough to implement correctly when it is needed, how do we expect to implement it optimally when we are still guessing whether or not we need it?

A quick summary of the negatives:  We are spending time writing code for something we might need.  We are writing the feature the way we think we will need it in the future.  We are spending time and money documenting and testing a feature that we are guessing we will need and by the way we are also guessing how to best implement it.

If all of those (mostly financial) arguments aren’t enough to convince you, let’s take a look at some down sides from an architect or developer’s point of view.

If code is in a release you have to assume it is being used.  When it comes time to change the code you think you needed, you are going to spend time figuring out how to change it without breaking the (imagined?) user base.  This might involve migrating data, configurations, backup procedures, reports, integration work flows etc.  When it comes time to change the code you really do need you must consider all of the code.  This includes the code you don’t realize that you don’t need – if it is in production, how can you be confident in saying “oh, we really don’t need that code”.  This really stifles our ability to modernize our code.  Even if you do find a way to refactor the bloated code base not only will you have to change the existing code but you will have to change the tests, documentation, and training materials.

Let the business analysts, user base, and marketing folks decide what features your product needs and when it needs it.  I would rather architect and design a system based on things that are known.  I don’t ever want to tell somebody that the system is the way it is because I thought we needed some functionality that turns out to be useless.  When we do a good job of designing and reviewing our system we can be confident that we can refactor our code to implement major functional changes when they are understood, needed, and the highest priority.

My design review checklist

No comments:

Post a Comment