Mark Needham

Thoughts on Software Development

TDD, small steps and no need for comments

with 7 comments

I recently came a blog post written by Matt Ward describing some habits to make you a better coder and while he presented a lot of good ideas I found myself disagreeing with his 2nd tip:

2. Write Your Logic through Comments

When it comes to coding, there are many tenets and ideas I stand by. One of this is that code is 95% logic. Another is that logic doesn’t change when translated from human language into a programming language.

What this means is that if you can write it in code, you can write it in a spoken language like English or French.

Instead of just jumping into coding the function, I could step back and write the logic in plain English as comments.

I’ve tried this approach before and although it can be useful I found that quite frequently I ended up with a more complicated solution than if I’d driven it out with a test first approach.

The advantage of driving the code from examples/tests is that it helps to put you in a mindset where you only need to care about one specific way that a particular object may be used.

As a result we often end up with simpler code than if we’d tried to imagine the whole design of that object up front.

I find it more difficult to keep a lot of code in my head but having just one example is relatively easy. The less code I have to think about at any one time the less mistakes I make.

As we add additional examples which describe different ways that the object may be used I’ve often found that the code ends up becoming more generalised and we end up with a simpler solution than we might have imagined when we started.

Matt goes on to say:

This way, I can think through the full logic and try to iron out the wrinkles before I actually get into writing the code. I’ve found this to be an incredibly valuable habit that tends to result in fewer bugs.

Using a TDD approach “allows us to describe in code what we want to achieve before we consider how” so the examples that we write provide an executable specification of what we expect the code to do.

I don’t have a problem with making mistakes when coding. I make mistakes all the time but having the safety net of tests helps me fix them pretty quickly.

Matt ends this section with the following:

As a bonus, since I will rarely actually delete the comments, writing the logic through comments also means that my code will already be documented, making it easier for others to follow my logic if they ever have to work on it, or even just for myself, if I have to come back to it several months or years down the road!

There are other ways of documenting code which don’t involve peppering it with comments. We can write our code in a way that reveals intent such that instead of having this:

// FUNCTION: Lock On Time
// This function will accept two time values, indicating the range through
// which it should return an unlocked status.
 
  // Create a new data object
 
  // Using the data object, get the current time
 
  // IF the current time falls within the range passed to the function
 
    // Return false – meaning that we are currently unlocked
 
  // ELSE
 
    // Return true – meaning that we are currently locked.
 
  // ENDIF
 
// END FUNCTION

We have something closer to this:

public bool ShouldBeLockedBasedOn(DateTime startOfTimeRange, DateTime endOfTimeRange)
{
	var dataObject = CreateDataObject();
	var currentTime = dataObject.CurrentTime;
 
	if(currentTime.IsBetween(startOfTimeRange, endOfTimeRange) 
	{
		return false;
	}
	return true;
}

…where ‘IsBetween’ would be an extension method on DateTime. We could have that as a private method but I think it reads better this way.

Comments don’t tend to be maintained in the same way that code is from my experience so as soon as the code around them changes we’ll find that they quickly become misleading rather than helpful.

There are certainly times when it makes sense to put comments in code but using them as a substitute for writing intention revealing code isn’t one of those!

Written by Mark Needham

July 23rd, 2010 at 2:52 am

Posted in Testing

Tagged with

  • Pingback: Tweets that mention TDD, small steps and no need for comments at Mark Needham -- Topsy.com

  • http://www.ifactoryinc-ifrp.com Claudio Oliva de Lyra

    Hi Mark,

    Another great article. I think we are tuned on this subject. Let me add some of my personal thoughts.

    The topic reminded me of an old software maxim: “don’t debug comments, comments lie”. And why it is so? Because comments, like documentation, inevitably decays along time. This is the expected behavior of ‘live’ systems.

    History tells that the strategy of ‘bringing documentation INTO the codebase’, via javadoc-like tools or via pure comment lines, unfortunately failed to solve the problem.

    The assertive that “logic doesn’t change when translated from human language into a programming language” sounds a bit naive. A lot of questions can be raised, like ‘when translated in which programming language?’ or ‘in which style of programming?’ or ‘in which level of detail?’ or still ‘for how large and complex type of program?’

    Going to the other extreme: a great article on XP tenets influenced me for a period of time. I have always been an advocate of TDD and intention-revealing coding, but then I was seduced by the siren song: no comments whatsoever. I have tried this path and I can say from my experience that it does not work either, not for large-scale distributed applications. Down the road, at some point, you will miss those concision hints that should have been sprinkled in the right places.

    Today I believe that comments are necessary for the benefit of future generations, echoing the reasons and decisions of the past.

    Actually, the ‘middle path’ is frequently the best.

    Link to the article mentioned above: (I was surprised I could still find a reference) http://www.drdobbs.com/184414826;jsessionid=5XTLA3BFL4XOTQE1GHOSKHWATMY32JVN

  • http://www.markhneedham.com Mark Needham

    @Claudio – I haven’t read the article you linked to yet but I just wanted to agree with your thoughts on the middle path. Comments are certainly useful for describing why non obvious design choices have been made.

    One example which happened on a project on the same client as me was related to the way objects were being queried from the database via Hibernate. The code was written in quite a hacky way to get around a performance problem and some guys decided to refactor it to the clean solution which was totally non-performant! Comments around that type of code would be really useful.

  • Pingback: Random Links #231 | YASDW - yet another software developer weblog

  • INTPnerd

    Like most things, I like a combinational approach. I like to use TDD and also sometimes write the implementation in comments. Notice the blog post said
    “this is a very simplistic example, but I do use this technique on a regular basis when I need to build a function that is notably more complex.”

    I don’t normally use comments in this way, but if I am writing a complex algorithm, and I am struggling with it, I use this. However I would create a real method with the implementation missing with the comments inside the method. I would also attempt to make the actual code just as readable as the comments and then delete the comments. I have seen real code written for a commercial website where the comments were less readable than the code it was documenting.

    I believe it was in the book Clean Code by “Uncle Bob” where he explained that any time you have to wite a commen

  • INTPnerd

    Somehow I posted that comment before it was finished. Carrying on…

    I believe it was in the book Clean Code by “Uncle Bob” where he explained that any time you have to leave a comment in your code, this is not something to be proud of, but it means you failed to express yourself sufficiently in the code itself. He was not saying that you should never have comments, but that you should try to make them unnecessary. When you can’t do this, comments are a necessary evil, not something to take pride in.

    I do agree with you that the reason for a design decision something that needs to be commented more often than the meaning of your code.

  • http://alexandregazola.wordpress.com Alexandre Gazola

    In my experience, code comments might be useful to rapidly think through a solution, especially a more “algorithmic” one. Nevertheless, I’m completely in favor of not using code comments in the final code, except for possibly documenting the public interface (though in this case the test suites could be a far better way of doing this) or to explain complex pieces of code. I read somewhere that “code comments are deodorant for poorly written code”.

    Cheers!