Jason in a Nutshell

All about programming and whatever else comes to mind

Enemies of Test Driven Development part II: YAGNI

Posted by Jason Baker on January 11, 2009

Just like in this post’s predecessor, don’t take the title of this post to mean that YAGNI should be abandoned.  YAGNI is still a very good principle that has saved me from writing a lot of crap code.  But many of us are trained to apply it in such a manner that runs counter to Test Driven Development.

Let’s take the following scenario.  I have a wrapper around one of the components of my data model.  The idea is that you insert data into it and then flush it, like so:

wrapper.Insert(some_collection);
wrapper.Flush();

The idea being that as soon as this code is ran, the contents of some_collection will be inserted into a database.  Let’s look at how the Flush method works at the backend:

void Flush()
{
    using (var dc = new SomeDataContext())
    {
        Flush((ISomeDataContext)dc);
    }
}

void Flush(ISomeDataContext dc)
{
    //do stuff with dc
}

Just to clear up any doubts you may have, the latter overload of Flush is not used in the production code anywhere.  I added this in just to make the code more generic.

You are going to need it

For those of you properly trained in the arts of YAGNI, these last two sentances probably set off alarm bells.  But take a look at this code:

class MockDC : ISomeDataContext
{
    public bool MethodCalled {get; set;}
    public void MethodThatMustBeCalledByFlush () {MethodCalled = true;}
}

[TestMethod]
public void TestFlush()
{
    var wrapper = new SomeWrapper();
    wrapper.Insert(stuff);

    var dc = new MockDC();
    wrapper.Flush((ISomeDC)dc);
    Assert.IsTrue(wrapper.MethodCalled);
}

Newbies to Test Driven Development (myself included) tend to find it difficult to write code that serves no purpose other than to enhance testability.  The thing is: code that makes other code more testable is needed.  And the above tests either wouldn’t have been possible or would have been hideously complicated without overloading Flush to be more generic.

So what is YAGNI good for?

Some people feel that TDD has largely subsumed YAGNI.  I can definitely see where they’re coming from.  But I think that YAGNI is still a good basic principle.

YAGNI is much like optimization in that it’s very difficult to apply at a micro-level.  Thus, if you find that you’re not adding necessary methods because of YAGNI, you’re probably using it wrong.  YAGNI is best applied at a high level.

One of my first assignments at my current job was to write a program to transfer some stuff from one database to another.  I thought I would try to go a bit above and beyond the call of duty.  See, my job has a lot of programs like these.  Just think of how much duplicated code must be out there!  Why not write some kind of framework to make this kind of stuff easier and allow code reuse?

The sky was the limit from this point on.  Before too much longer, I had a model that included the pipeline and observer design patterns.  Along with a component model that allowed linking components in all sorts of need ways.  I got about halfway through it.  At a certain point, it just became too difficult to make the .Net type system work with what I was wanting to do.

I eventually just decided to code it the “regular” way without any of that cool stuff.  I finished it within a few days.  Now, a judicious use of YAGNI would have saved me a lot of time here.  So what’s the lesson?  With apologies to Albert Einstein, the lesson is to apply YAGNI as much as possible, but no more.  Once you get a sane approach going, I think you’ll find that YAGNI is a tool that will help your programming rather than hurt it.

Other Posts:

One Response to “Enemies of Test Driven Development part II: YAGNI”

  1. [...] Enemies of Test Driven Development part II:  YAGNI [...]

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

 
Follow

Get every new post delivered to your Inbox.

%d bloggers like this: