BDD is to YAGNI as TDD is to BDUF

I’m going to give this analogy a 43% rating in terms of how strongly I feel about it, but for what it is worth…..

BDD/Context Specification encourages you to write the code, and only the code, that your application actually needs right now.  TDD encourages to write the code that you need right now as well as the code you think that you are going to need.

YAGNI is a concept that is simple to state, but can be difficult to understand in its implications.  This is actually true about the concept of BDUF as well.

YAGNI (“you ain’t gonna need it” is one of its colloquial forms) at the least suggests you should not attempt to solve the problems that you think you will need to solve, but instead to focus on the problems that you actually do need to solve right now.

BDUF (“big design up front”) can, at the least, be seen as the opposite of YAGNI, where you attempt to construct some grand(er) design that encompasses a wide range of future possibilities ahead of when they are actually relevant.

It’s easy to explain why these concepts can be abused or misused, and that’s always a lot of fun, but just a couple of points here.  Where BDUF in its truly negative form can be seen is best with an example.  On more than one occasion, I’ve been in situations where people have a need for logging.  Ignoring the fact that logging is a solved problem, sometimes people just think they need to create a custom logging solution.  That’s already bad enough, but off-topic.  Suppose the immediate need is that you need to log error messages relating to database calls.  An urge that some people can’t resist is to take this immediate need, and then decide that while, obviously, the custom logging system should log error messages related to database calls, it should also log error messages related to, oh, email calls, web server calls, calls to your Mom, you get the idea.  So, some grand design of an uber-logging system is, well, designed, without any actual specific cases or scenarios that are needed right now.

<digression>In the middle of one such disastrous meeting related to such a logging system design, I asked the ‘architect’ if he had ever heard of YAGNI.  He said no.  I then explained it.  He said, “Yes, I know what that is.”  And then proceeded on.  Fantastic.</digression>

(Ignoring the fact you really shouldn’t be designing a custom logging system, unless you actually need it, which you might), YAGNI counsels you to stick with the exact need, the need to log error messages related to database calls, and build the system that does that (and implicitly, does it well).  Then, later on, if you need to add other types of logging, you refactor the existing system to handle it.

<digression>If you are nuts enough to try to design a custom logging system, and apply BDUF to it, you end up with an API that makes no sense, because you end up trying to come up with some generic terms that applies to all situations, including those as yet not present but we think we will really need scenarios of which we have as of yet no concrete examples so we are pissing in the wind situations.</digression>

TDD encourages BDUF

Sort of.  TDD starts at the class level (generally), so you start to design a class outside of specific requirements.  That is, you might have specific requirements that suggests to you that you need a specific class, but once you start working on that class, it is very easy to start to write the specific design of that class outside of very specific requirements.

It’s hard to explain this well without a specific example, and it is hard to use an example that is guaranteed to be widely understood, so I’ll use one that I’ve worked on previously that isn’t completely obscure.  Suppose you are a retailer that deals with various suppliers in terms of how inventory should be managed, and you are working on a new system for a client.  If you’ve ever dealt with multiple suppliers before, you will have experience of the types of scenarios that might possibly come up.  This experience shouldn’t be ignored, but a problem that can arise is trying to design a class in a new system that handles all of those scenarios up front.  It’s a natural inclination, and, again, if you have previous experience in the domain, it makes a certain amount of sense to consider those scenarios.

The problem is that, since TDD doesn’t really give you an exact starting point besides the need to write the class(es) in question, you don’t have a guard to tell you when you are doing too much or too little.

BDD encourages YAGNI

With BDD, you start with what the system will do, from the start, with the supplier (or suppliers) you have, at the time.  What are the requirements for what I need right now?  What are the requirements that my existing suppliers have for my current need?  Since BDD style processes are supposed to involve the end user from the start, you are much more likely to have very specific requirements, than if you have developer-centric TDD requirements around a need to have some inventory management classes.

Moreover, BDD is more likely to give you hard starting and stopping points in terms of requirements and knowing when you are done.


YAGNI can be done horribly wrong, where you build systems that are so locked into current requirements that you can’t handle new ones.  And BDUF can be done right, where you reasonably design for future requirements that are not quite yet present, but reasonably expected. 

Knowing where to draw the lines involves both a certain level of experience and knowledge of the domain in question. 

<digression>I’m more and more convinced that the ‘proliferation of classes’ practice, where you, e.g. instead of designing uber inventory management classes, you design SupplierAInventoryManagement classes and then, when the requirement arises, you design SupplierBInventoryManagement classes, etc. and then integrate them, is the right way to go.</digression>

Regardless, a fundamentally fatal flaw of TDD has always been that it doesn’t give necessary guidance to developers of where to start and stop, whereas BDD gives you exactly that.

posted on Sunday, March 06, 2011 11:32 PM Print
# re: BDD is to YAGNI as TDD is to BDUF
Stefano Ricciardi
3/23/2011 6:14 AM
Since your post is about acronyms, I couldn't resist to mention that writing a custom log system is a classical example of the NIH syndrome (Not Invented Here).

Based on my 2 years experience with TDD (which I know is not that much time), I haven't found TDD pushing me towards BDUF. I usually have some responsibilities I expect the class to satisfy, write test methods around those responsibilities, implement the required behavior and then pass on. Rarely do I find myself over-engineering the class to satisfy "future" possible needs. Then again, YMMV :)

# re: BDD is to YAGNI as TDD is to BDUF
3/26/2011 9:27 PM

I did say I gave the analogy a 43% rating ;).

My guess is that the reason why you don't feel that TDD pushes you towards BDUF is that you are a really good developer. I'm a firm believer in a 'principle' that can be generically explained as: "If you take a team of really good developers, then they can take the most waterfall of BDUF situations and produce high quality, highly maintainable software. If you take a team of mediocre developers, you can have them use the most highly agile of processes, and they'll screw it up."

When you say "I usually have some responsibilities I expect the class to satisfy", where do those responsibilities come from? I'm willing to bet at least $17 that they come from a BDD-style understanding of how that class fits into overall business requirements.

Post Comment

Title *
Name *
Comment *  
Please add 8 and 1 and type the answer here: