Monday, March 23, 2015

Complacency is the enemy

Working as a jack-of-all-trades agile coach, one of the biggest problems I face is the stagnation of my knowledge. If you do not stretch yourself by working with more knowledgeable people from time to time, you don't develop. You may even go backwards. Prescott's Pickle Principle summarises this as:
"Cucumbers get more pickled than brine gets cucumbered"
or, put another way,
"A small system that tries to change a big system through long and continued contact is more likely to be changed itself"
(from Jerry Weinberg's excellent Secrets of Consulting book)

Much as I hate to admit it, I am that "small system". So it is healthy and fun to occasionally sit down with like-minded people, and re-baseline your knowledge.

That is exactly what I did the other Saturday. I survived a dull and freezing Wimbledon to attend Jason Gorman's "Intensive TDD Workshop" (the one-day super-intensive version of this one).

I won't go into too much detail about the course itself. The point of this article isn't to review the course. Suffice to say that it is the entry level course for TDD, starting right from the beginning. It was immensely enjoyable even as someone who has practiced TDD for a while, and highly recommended. What was most interesting is the way Jason highlighted a couple of interesting wrinkles in my own coding style, and how I had become inadvertently slightly pickled.

Have a read, and see if you recognise any of these in yourself. Or maybe you have other habits that you need to clean up?

Habitual Coding

While working on one of the exercises, I wrote something like the following Java code:

    public String getString() {
        StringBuffer buffer = new StringBuffer("1");
        for (int i = 2; i <= 100; i++) {
            buffer.append("," + i);
        }
        return buffer.toString();
    }

As we all know, String objects are immutable. Every time you modify one, a new one is created. So to build a larger String from components, you use a StringBuffer, don't you? It's the way I was taught all those years ago when learning Java (I can't remember where from - book, article, person, no idea).

To my surprise this was called out. What's wrong with this? Simple:
Where is the failing test that is making me use a StringBuffer? What is stopping me from simply using a simple String object and appending to it? 
It is not using the simplest possible design that would work. It is premature optimisation - the root of all evil. If performance, or memory, becomes a problem in the future, then write a failing test that shows it, then code to fix it. Hardcore, Dude!

I am now consciously looking out for other constructs I use habitually that do not have a a failing test to justify their existence.

Only refactor from Green - no matter how tempting or easy it seems


Squirrel! It's the programmer's equivalent. You see something that needs tweaking, or that needs changing. So you quickly fix it. Squirrel! You see something else, and fix it. Squirrel! And suddenly you find yourself in a quagmire of changes, uncertain what is breaking what, where or how.

Again, this comes back to only ever changing production code on a failing test, and only ever refactoring on a green. It was a timely reminder to not chase squirrels, and to focus on a single task instead. Be aware when you become distracted. Be strict with yourself. Use a todo list to get away from temptation and get things out of your brain.

Refactor, Refactor Then Refactor Some More

Put simply, that Saturday in sunny Wimbledon I rediscovered the fact that I am not a "finisher". This comes out in all the personality tests I have taken over the years, most recently Belbin (I am a combined TeamWorker, Coordinator, Plant, if anyone's interested).

Now, this does not make me a Bad Person, but it does mean I need to watch that I refactor my code to its natural conclusion each time. I have a tendency to tolerate duplication more than I should in order to move onto the next thing to do. A tendency easily fixed by pairing with a "Completer Finisher"

Use Parameterised Tests more

When was the last time you used a parameterised unit test to check a range of similar things? I knew JUnit could do it, but had to look up the syntax, not having used it for a helluva long time. Yet it can make a huge difference to test readability. And nUnit's capabilities are more advanced again.

Once I get some time to tidy up the code, I'll post some examples. But do give the whole parametrisation thing some thought - it can and does help. And it seems to be much underused.

2 comments:

Allan Kelly said...

Thanks, good points

Chris said...

This article is a bit of a work in progress - "watch this space", as they say. But I wanted to get the initial ideas out there since I find that my little foibles are commonplace in TDD practice - which is probably how I picked them up without noticing. Osmosis.