craftmanship

Facilitating the Global Day of Coderetreat 2013 in Amsterdam

On the 14th of December 2013 – the Global Day of Coderetreat was held at ZilverlineI have experience with coderetreats and also organised one at the 7th of january in 2012, and the GDCR12.

This time I both hosted and facilitated this event. This means that besides practical stuff I also did the talking which I will explain further in this post. This was the first time I did this and I’d like to share how it was. If you want to get an impression of the day you can have a look at this slideshow.

A big thanks to Bob Forma and Diana Sabanovic who helped me with the hosting aspects throughout. This enabled me to mostly focus on facilitating.

I was anxious, especially since last years GDCR was very well done. Back then I had a great experience and I was not sure if I could give the participants the same experience. Yet, I wanted to do this: I just love sharing knowledge and give people something to learn or think about.

After attending the GDCR Facilitator Training by Jim Hurne, I had a clear image of how I wanted the participants to experience the Coderetreat: People having fun, learning from each other and the constraints given.

Thats it.

(more…)

Regression – Lets stop it!

I hate it.

You change something and you can’t tell if your change broke something in the system.

If you’re lucky, you did not break anything. Or nobody noticed it.
Next to that, on the same scale of luck, the potential bugs are found in the manual testing phase.

But often there is no time to do all the regression testing by hand. It will take days and days, and the change you made looked so insignificant. It should go live. What could possibly go wrong?.

Then it happens. You’re live, your changes work, but the inevitable happens. Regression!

Of course, this has to be fixed. We can’t let our customers have a product with new features while the features of the previous version(s) are broken.

And so the patching process begins.

I call it patching, because often you are not done with one patch. While you were working hard to get the first patch live, other regression bugs are found and need to be patched asap as well! And so you end up with a few patches. You could be done with with a few patch releases. But it could easily extend ten-fold.

This process is very stressful for the customer and the development team. As the team is working to get these patches out soon, the customer is unhappy with his ‘broken system’. Even worse, once a few bugs are found, more testing is done on the live system to make sure everything still works, and more regression bugs poor in, adding up to the stress. To the development team it begins to look like…

From the customer’s point of view, it looks like the team working on the product is not in control. It is as if the team does not seem to know what they are doing. To them their product, which seemed rock solid at start, is degrading to a house of cards.

You can debate about high and low impact issues, and the matter of urgency to fix these issues. The perception of the customer is likely to be the same, regardless.

This is how I see it:

It is us developers who are responsible for letting regression happen.

Not testers.
Not project managers.
Not stakeholders.
Not the customer.

It is us and us alone.

We write the code, we change the code, we are in control of the code (at least we should be!).

Even if you happened to be depending on a third-party system, it is your job to keep an eye out on that system. Verify that it behaves as you would expect it to. Why? Your system depends on the behaviour of another system, trusting that this behaviour does not change is not enough. You have to be *sure*.

Its all about attitude
Do you always deal with regression bugs after each release?

Stop accepting it, it is not normal.

Rather, start thinking about how you can prevent this. Don’t look how other people could prevent this. Think of what you could do right now. There are many ways to reduce the amount of regression bugs. For instance: add tests before changing any code. Fixate the behavior with black box tests. When you refactor, keep running your tests so you know you did not break existing behaviour. Add new tests for new features you introduce. Create a test suite that you can trust. Make integration tests. Is it hard to write tests? Make it easier. Don’t back away from the code, it is your code and you should be in control.

Besides the code, improve your own skills. Start reading about how to deal with legacy code. Attend a legacy code retreat to hone your skills. Practice, practice, practice! Get better.

Reap what you sow in your daily work.

But isn’t the whole team responsible?
Ah, of course! But does that mean that you, as a developer can now do less? Would it be okay in a team to not test, because you have testers? (“its their job right?”).

In a team we all have our strengths and weaknesses.

We understand code, and we can change code. No other role in your team is responsible for understanding the code then you. Being in a team does not make you less responsible.

Again, it is all about attitude. Stand for your craft, deliver high quality work and make sure the system is in check. It should be you who controls the system.

Attitude, again
There are developers out there who really think they know everything of the system. And to be honest, I once had a time where I always knew what changes had impact and what I could do. And even though I was right about the impact on changes…

…I was at least wrong as many times as I was right.

But sometimes it is not just being over-confident. Sometimes it is being ignorant, or even arrogant.

Please, don’t be like this guy…

Just because it is hard, doesn’t mean you shouldn’t do it
Regression is a pain. It can be dealt with.

It is not easy.

You will not completely eliminate regression bugs. But with the correct mindset, tools and safety-net(s), you will greatly reduce the amount of regression bugs.

It is necessary. Just do it. For the love of our (your!) craft, do it, for everyone who depends on us:

The customer.
The stakeholders.
The project managers.
Yes, even the testers.

The difference between TDD and Test First Development

Recently I promoted to do TDD, instead of “Tests First” development. Some people asked me what the difference is between them. In both cases we write tests first right?

So what is the difference?

I believe the difference is this:

Test First decribes your solution. TDD describes the problem

The difference could probably be explained best when using the coderetreat I had organized at the beginning of this year. Within this session I had experienced a great example to tell the difference between Tests first and TDD. To clarify the difference in this blog, we will be writing an implementation of Conway’s Game Of Life. It has the following rules:

  1. Any live cell with fewer than two live neighbours dies, as if caused by under-population.
  2. Any live cell with two or three live neighbours lives on to the next generation.
  3. Any live cell with more than three live neighbours dies, as if by overcrowding.
  4. Any dead cell with exactly three live neighbours becomes a live cell, as if by reproduction.

And it looks like this:

Image

Game Of Life in Action - Image from Wikipedia

Your assignment:

Write code that implements to the four rules above. It should be possible to apply these on an infinite grid

Test First describes your solution:
So the rules talk about “cells” and in your mind you’re already trying to solve this puzzle. In fact, I bet you’re already thinking about some array to put this matrix of cells into. Using a matrix we can easily determine neigbours and solve this puzzle…

We start with the first rule: “Any live cell with fewer than two live neighbours dies, …“.

We know it needs neighbours, so we need some boilerplate for that right?

The first test looks like this:

public class CellTest {

	@Test
	public void mustReturnTrueWhenAlive() {
		Cell cell = new Cell(1,0);
		Assert.assertTrue(cell.isAlive());
	}

}

Since we’re doing TDD (atleast we think it is, we’re actually doing Tests First…), we need to create this Cell class to make it compile.

public class Cell {

    private long x, y;

    public Cell(int x, int y) {
        this.x = x;
        this.y = y;
    }

    public boolean isAlive() {
        return true;
    }
}

Before we can do anything with counting the number of neighbours, we need to determine what a neighbour is. Since adjecent cells are counted as neighbours, we start writing tests for this:

	@Test
	public void mustReturnTrueWhenNextToAnotherCell() {
		Cell cell = new Cell(1,0);
		Cell adjecent = new Cell(1,1);
		Assert.assertTrue(cell.isAdjecent(adjecent));
	}

	@Test
	public void mustReturnFalseWhenNotNextToAnotherCell() {
		Cell cell = new Cell(1,0);
		Cell adjecent = new Cell(3,3);
		Assert.assertFalse(cell.isAdjecent(adjecent));
	}

And along with it the code:

public class Cell {

    private long x, y;

    public Cell(int x, int y) {
        this.x = x;
        this.y = y;
    }

    public boolean isAlive() {
        return true;
    }

    public boolean isAdjecent(Cell adjecent) {
        long diffX = Math.abs(adjecent.getX() - x);
        long diffY = Math.abs(adjecent.getY() - y);
        return diffX == 1 || diffY == 1;
    }

    public long getX() {
        return x;
    }

    public long getY() {
        return y;
    }
}

Wait, stop, halt!

If the above sounds familiar, then I’ve got news: This is not TDD

Lets get back to the original question, what did we try to implement? Ah, it was the question:

“Any live cell with fewer than two live neighbours dies, as if caused by under-population”,

So where is the corresponding test for that?…

In fact, we have already three tests and a bunch of code, and we still are not able to answer the question.

What we’ve done so far is write tests first in order to prove a solution we already had in our minds. We did not let the tests guide us to a design. In fact, we already had a design in our heads and made the tests conform to those.

Lets do it in TDD, for real…

So how is it done ? – Test Driven Development

With a clean slate, we start over. And we start with the first rule:

“Any live cell with fewer than two live neighbours dies, as if caused by under-population”

So we create a test (we call it Test, because we do not think about Cells yet, in fact, we are only thinking about this very question).

    @org.junit.Test
    public void anyLiveCellWithFewerThanTwoLiveNeighboursDies() {
        int neighbours = 1;
        Assert.assertTrue(neighbours < 2);
    }

So what does this do, it basically returns true when neighbours is lower than two. We do not call methods yet, we simply have our implementation within the test itself. In this phase, we already had Red (non compiling), Green (compiling and green test). On to refactor. How to get it more descriptive? We could do something like this:

    @org.junit.Test
    public void anyLiveCellWithFewerThanTwoLiveNeighboursDies() {
        int neighbours = 1;
        boolean shouldDie = neighbours < 2;
        Assert.assertTrue(shouldDie);
    }

Do we need to do anything else? Certainly! But the essential rule is there already. It is one simple statement, no neighbour checking yet. And in fact, we will not need it to implement the four rules! Lets continue. I am serious, we will not modify the above code yet. We have yet to implement the other rules. Lets pick the second:

“Any live cell with two or three live neighbours lives on to the next generation.”

We have actually two cases here, for two and three live neighbours. Lets start with two:


    @org.junit.Test
    public void anyLiveCellWithTwoNeighboursLivesOn() {
        int neighbours = 2;
        boolean shouldLiveOn = neighbours == 2;
        Assert.assertTrue(shouldLiveOn);
    }

Not that much different is it? How about we add the third test for the second rule:


    @org.junit.Test
    public void anyLiveCellWithThreeNeighboursLivesOn() {
        int neighbours = 3;
        boolean shouldLiveOn = neighbours == 3;
        Assert.assertTrue(shouldLiveOn);
    }

The total test class looks like this now:

public class Test {

    @org.junit.Test
    public void anyLiveCellWithOneThanTwoLiveNeighboursDies() {
        int neighbours = 1;
        boolean shouldDie = neighbours < 2;
        Assert.assertTrue(shouldDie);
    }


    @org.junit.Test
    public void anyLiveCellWithTwoNeighboursLivesOn() {
        int neighbours = 2;
        boolean shouldLiveOn = neighbours == 2;
        Assert.assertTrue(shouldLiveOn);
    }

    @org.junit.Test
    public void anyLiveCellWithThreeNeighboursLivesOn() {
        int neighbours = 3;
        boolean shouldLiveOn = neighbours == 3;
        Assert.assertTrue(shouldLiveOn);
    }
}

We have done some little TDD cycles already. We started describing the problem domain, and we added the minimum amount of code to make this work. We did not yet start write any production code yet. Now one of the most important steps in TDD should be taken: Refactor. (Remember it is Red – Green – Refactor!)

With the third test, we clearly see duplication. The shouldLiveOn can be extracted to a method. Lets do that:

import org.junit.Assert;

public class Test {

    @org.junit.Test
    public void anyLiveCellWithOneThanTwoLiveNeighboursDies() {
        int neighbours = 1;
        boolean shouldDie = neighbours < 2;
        Assert.assertTrue(shouldDie);
    }

    @org.junit.Test
    public void anyLiveCellWithTwoNeighboursLivesOn() {
        int neighbours = 2;
        Assert.assertTrue(shouldLiveOn(neighbours));
    }

    @org.junit.Test
    public void anyLiveCellWithThreeNeighboursLivesOn() {
        int neighbours = 3;
        Assert.assertTrue(shouldLiveOn(neighbours));
    }

    private boolean shouldLiveOn(int neighbours) {
        return neighbours == 3 || neighbours == 2;
    }
}

We could refactor out the neighbours var to a constant, which should give us even smaller tests.

At this point we have now our first method which could eventually be moved out of the test class into some other class (we have yet to think of a name for). As you can see, the design of our code is being driven by the tests. So this may like trivial and like ‘cheating’. In fact, as I see it we are actually answering the real questions. We tend to write code for stuff we cannot possibly be sure of that it is correct. Did you see any line say that the Game of Life in this situation should be on a 2D grid? What if it would be 3D? What if we did not know yet if it would be 2D or 3D?

This sounds a lot like real-life isn’t it? Where your customer does not always know exactly what he wants.

Another good thing is, we can implement all rules like this. Eventually we end up with a test class that contains several methods. From there on we can think of a logical way to group them. Methods grouped together will form classes. We tend to group methods logically. When we define the problem domain we know better what classes should exist. Again, our tests drive the design. Instead of the other way around.

Here is an impression how the four rules implemented might look like:

package com.fundynamic.coderetreat;

import org.junit.*;

public class Test {

	public static final int StarvationThreshold = 1;
	public static final int OverpopulationThreshold = 4;
	public static final int MinimumRevivalThreshold = 3;
	public static final int MaximumRevivalThreshold = 3;

	@org.junit.Test
	public void liveCellShouldDieIfLessNeighboursThanStarvationThreshold() {
		int amountNeighbours = StarvationThreshold;
		Assert.assertEquals(false, livesOnToNextGeneration(amountNeighbours));
	}

	@org.junit.Test
	public void liveCellShouldDieIfNeighboursEqualToStarvationThreshold() {
		int amountNeighbours = StarvationThreshold;
		Assert.assertEquals(false, livesOnToNextGeneration(amountNeighbours));
	}

	@org.junit.Test
	public void liveCellShouldLiveIfTwoNeighbours() {
		int amountNeighbours = StarvationThreshold +1;
		Assert.assertEquals(true, livesOnToNextGeneration(amountNeighbours));
	}

	@org.junit.Test
	public void liveCellShouldLiveIfThreeNeighbours() {
		int amountNeighbours = 3;
		Assert.assertEquals(true, livesOnToNextGeneration(amountNeighbours));
	}

	@org.junit.Test
	public void liveCellShouldDieIfFourNeighbours() {
		int amountNeighbours = 4;
		Assert.assertEquals(false, livesOnToNextGeneration(amountNeighbours));
	}

	@org.junit.Test
	public void liveCellShouldDieIfEightNeighbours() {
		int amountNeighbours = 8;
		Assert.assertEquals(false, livesOnToNextGeneration(amountNeighbours));
	}

	@org.junit.Test
	public void deadCellShouldReviveIfMinimumRevivalThreshold() {
		int amountNeighbours = MinimumRevivalThreshold;
		Assert.assertEquals(true, revivesInNextGeneration(amountNeighbours));
	}

	@org.junit.Test
	public void deadCellShouldReviveIfMaximumRevivalThreshold() {
		int amountNeighbours = MaximumRevivalThreshold;
		Assert.assertEquals(true, revivesInNextGeneration(amountNeighbours));
	}

	@org.junit.Test
	public void deadCellShouldNotReviveIfLessNeighboursThanMinimumRevivalThreshold() {
		int amountNeighbours = MinimumRevivalThreshold -1;
		Assert.assertEquals(false, revivesInNextGeneration(amountNeighbours));
	}

	@org.junit.Test
	public void deadCellShouldNotReviveIfMoreNeighboursThanMaximumRevivalThreshold() {
		int amountNeighbours = MaximumRevivalThreshold +1;
		Assert.assertEquals(false, revivesInNextGeneration(amountNeighbours));
	}

	private boolean livesOnToNextGeneration(int amountNeighbours) {
		return amountNeighbours > StarvationThreshold && amountNeighbours < OverpopulationThreshold;
	}

	private boolean revivesInNextGeneration(int amountNeighbours) {
		return amountNeighbours == MinimumRevivalThreshold;
	}
}

But you did not even get to any cell? How is this any good?

It is true that cells play a role in the Game of Life eventually. But they do not play a role in answering the four questions. In fact, what are cells? We might be talking about squared cells, but perhaps you want to write your 3d version of it. Or you might want to use hexagons. If you put the rules logic into a cell, it gets very hard to modify your code because you have put too much responsibility in one class.

TDD prevents you from doing this.

Also, if you started with using Cells and the matrix and all that. I would wonder how you would implement the last rule (reviving cells). How would you solve this problem?

Bottom line

Writing tests before your production code is not the same as TDD. It is about how your tests drive your design. Only then you can say if you are doing TDD or actually are just writing tests proving your own solution you have thought about before-hand.

It is hard to not think ahead of your design, and instead trust on our tests to let the design emerge itself. This requires practice. Practicing this can be done in coderetreats for instance.

The ten commandments of egoless programming

Ever heard of the ten commendments of egoless programming? I came accross them a while ago. I just thought of putting them here for history sake, these ten are actually quite good and should be cached on every search engine’s server as many times as possible.

I really like nr 6 a lot. How about you?

So, here a recite:

1. Understand and accept that you will make mistakes.
The point is to find them early, before they make it into production. Fortunately, except for the few of us developing rocket guidance software at JPL, mistakes are rarely fatal in our industry, so we can, and should, learn, laugh, and move on.

2. You are not your code.
Remember that the entire point of a review is to find problems, and problems will be found. Don’t take it personally when one is uncovered.

3. No matter how much “karate” you know, someone else will always know more.
Such an individual can teach you some new moves if you ask. Seek and accept input from others, especially when you think it’s not needed.

4. Don’t rewrite code without consultation.
There’s a fine line between “fixing code” and “rewriting code.” Know the difference, and pursue stylistic changes within the framework of a code review, not as a lone enforcer.

5. Treat people who know less than you with respect, deference, and patience.
Nontechnical people who deal with developers on a regular basis almost universally hold the opinion that we are prima donnas at best and crybabies at worst. Don’t reinforce this stereotype with anger and impatience.

6. The only constant in the world is change.
Be open to it and accept it with a smile. Look at each change to your requirements, platform, or tool as a new challenge, not as some serious inconvenience to be fought.

7. The only true authority stems from knowledge, not from position.
Knowledge engenders authority, and authority engenders respect—so if you want respect in an egoless environment, cultivate knowledge.

8. Fight for what you believe, but gracefully accept defeat.
Understand that sometimes your ideas will be overruled. Even if you do turn out to be right, don’t take revenge or say, “I told you so” more than a few times at most, and don’t make your dearly departed idea a martyr or rallying cry.

9. Don’t be “the guy in the room.”
Don’t be the guy coding in the dark office emerging only to buy cola. The guy in the room is out of touch, out of sight, and out of control and has no place in an open, collaborative environment.

10. Critique code instead of people—be kind to the coder, not to the code.
As much as possible, make all of your comments positive and oriented to improving the code. Relate comments to local standards, program specs, increased performance, etc.

An example of refactoring

As I have promised in my previous post, I would post an example of small refactorings in order to greatly improve the readability and understandability of code.

I own a little project called Dune II – The Maker, and I started writing it a little over 10 years ago. In those years I have learned a lot. I did not have much time in those days to apply my new knowledge to the project. You could say the software was rotting. In order to make it better I need to refactor a lot and I encounter the best examples to improve code without pointing fingers :). In any case I have experienced you have to make mistakes in order to get better. I hope you will learn from the mistakes I made.

So here is a little example I have just checked in the dune2themaker repository, I’ll give you the before (revision 411) and after (revision 412). Of course, I have taken smaller steps to get to the end result. First the original piece of code:

Revision 411 (before)

void cGame::think_winlose() {
	bool bSucces = false;
	bool bFailed = true;

	// determine if player is still alive
	for (int i = 0; i < MAX_STRUCTURES; i++)
		if (structure[i])
			if (structure[i]->getOwner() == 0) {
				bFailed = false; // no, we are not failing just yet
				break;
			}

	// determine if any unit is found
	if (bFailed) {
		// check if any unit is ours, if not, we have a problem (airborn does not count)
		for (int i = 0; i < MAX_UNITS; i++)
			if (unit[i].isValid())
				if (unit[i].iPlayer == 0) {
					bFailed = false;
					break;
				}
	}

	// win by money quota
	if (iWinQuota > 0) {
		if (player[0].credits >= iWinQuota) {
			// won!
			bSucces = true;
		}
	} else {
		// determine if any player (except sandworm) is dead
		bool bAllDead = true;
		for (int i = 0; i < MAX_STRUCTURES; i++)
			if (structure[i])
				if (structure[i]->getOwner() > 0 && structure[i]->getOwner()
						!= AI_WORM) {
					bAllDead = false;
					break;
				}

		if (bAllDead) {
			// check units now
			for (int i = 0; i < MAX_UNITS; i++)
				if (unit[i].isValid())
					if (unit[i].iPlayer > 0 && unit[i].iPlayer != AI_WORM)
						if (units[unit[i].iType].airborn == false) {
							bAllDead = false;
							break;
						}

		}

		if (bAllDead)
			bSucces = true;

	}

	// On succes...
	if (bSucces) {
		// <snip>

	}

	if (bFailed) {
		// <snip>

	}
}

The intention of the think_winlose() function is to determine if the player has won or lost, and if so it transitions the game state. These transitions have been snipped.

So when does a player win or lose? It depends if there is a ‘win quota’, or not. The win quota is a number, whenever it is above zero it means the player has to collect at least that many of credits (spice) in order to win. If the win quota is not set, the default win rule : destroy everything of the enemy, will be used. (do you notice I need this much text for just a simple rule? Which I could have prevented If I had code that said this in the first place? At the bottom of this post you can see what I mean :))

Lets take a look at the code and point out what could be done better:

  • There are two booleans bSuccess and bFailed. Which is confusing and ambigious. What is succesfull? What did fail? Why aren’t they one boolean?
  • There are comments all over the place, meaning we could refactor these pieces to code so comments are not needed. (Comments are seen as clutter and should be removed)
  • The code formatting could be done better. If statements should start with { and end with }, even with one line.

And there are more things you will probably find yourself. What I’ll do is point out a few things that could be improved. If you just want to see the final result, just take a look below.

Lets start with the booleans bSuccess and bFailed. Why are there two booleans and whey are they called so vaguely? A little bit of searching in the code and we find out that bSuccess actually means “Mission is accomplished” (player has won), and bFailed means the player has no units and structures (which implicates the player has lost the game). They are not the same boolean, because a player could be alive and not have yet won the game of course. Now we know they are not actually the same boolean, but their naming was vague. A simple “rename variable” made things easier to understand!

void cGame::think_winlose() {
	bool bMissionAccomplished = false;
	bool isPlayerAlive= true;

(when posting this I realize the two booleans are named differently, consistency is also important to improve readability, so either both should start with “is” or both with a “b”, I prefer the first though)

Right after the booleans a few for loops are used just to find out if there is anything alive for the player. A little bit below we see such for loops again, but for the AI. This is duplicate code and should be removed. Extracting them into a method and make them return a boolean value is easy to do:

bool cGame::playerHasAnyStructures(int iPlayerId) {
    for (int i = 0; i < MAX_STRUCTURES; i++) {
		if (structure[i]) {
			if (structure[i]->getOwner() == iPlayerId) {
				return true;
			}
		}
	}
    return false;
}

(Again, while posting this I realize this could be even improved a bit more, the iPlayerId should be called ownerId (or the getOwner should be a getPlayerId), so it is obvious we match two of the same kind. Now it could confuse us: is an owner the same as the playerId? Since I know it is, why isn’t it called that way?… :))

Since we extract these for loops we can now set the isPlayerAlive boolean immidiately instead of setting a variable within the loop as it was done in the original example above. Reducing 24 lines into one!:

bool isPlayerAlive = playerHasAnyStructures(HUMAN) || playerHasAnyGroundUnits(HUMAN);

The final result of revision 412 is shown below. It will clearly show the major improvement regarding readability and understandability. Any other developer who comes to this code can see what it does and it is almost a no-brainer.

Result revision 412

void cGame::think_winlose() {
	bool bMissionAccomplished = false;
	bool isPlayerAlive = playerHasAnyStructures(HUMAN) || playerHasAnyGroundUnits(HUMAN);

    if (isWinQuotaSet()) {
		bMissionAccomplished = playerHasMetQuota(HUMAN);
	} else {
		bool isAnyAIPlayerAlive = false;
		for (int i = (HUMAN + 1); i < AI_WORM; i++ ) {
			if (playerHasAnyStructures(i) || playerHasAnyGroundUnits(i)) {
				isAnyAIPlayerAlive = true;
				break;
			}
		}

		bMissionAccomplished = !isAnyAIPlayerAlive;
	}

    if (bMissionAccomplished) {
		// <snip>
		
	} else if (!isPlayerAlive) {
		// <snip>

	}
}

The tremendous power of tiny refactorings

More and more I am being intrigued by the power of a small code refactorings. The positive impact it has on the readability, the maintainability and understandability of your code is great. It keeps code clean(er) and since the changes you make are really small (I’ll demonstrate how small), the chance they will break things is small. Of course, with unit tests (you are writing them right?) making sure you did not break anything: a small refactoring is a low-risk high-benefit practice.

In my experience, small refactorings are undervalued. In fact, I undervalued them much myself since not too long ago. They are disregarded as refactorings that don’t help at all, because it is obvious what the code does. However, the flaw in this rationale, as I see it, is that the intended audience is not only you but also the other developer you work with. Also, you know what code does right now. But would you understand it as quickly if you did not look at it for a week and came back? Would another developer understand the code right away?

When working on code, you’re constantly trying to ‘translate’ the code in your mind in order to know what it is doing. Doing this it leads you to where the bugs are or the areas where you need to make changes, etcetera. This process of ‘translating’ code in your mind comes at a price. Literally the energy you need to burn in your brain to grasp the meaning of a piece of code: brainpower; The easier we understand code, the less brainpower we need. The less energy we burn by understanding what is going on, the more energy we have left to create new things, or fix that bug.

I’ve created a little example. The code below represents an implementation of a mail service. The mail service allows you to send an email using a method that uses 4 parameters: to, from, the subject and the message. When all parameters are filled, the email needs to be sent. That is the only requirement for now. Of course, later we might want to validate if the given email adress of from and to are valid. But for the sake of the argument, lets keep it simple. The following code is ‘mind-boggling’, compared to its simple intention:

public class MailServiceImpl implements MailService {

	public void sendMail(String from, String to, String subject, String message) {
		if (from != null && !"".equals(from) &&
			to != null && !"".equals(to) &&
			subject != null && !"".equals(subject) &&
			message != null && !"".equals(subject)) {
			// send the email
		}
	}

}

Basically what this says it that any field may not be null or an empty string. It took 4 lines for just to show. Even though you recognize the pattern of a ‘null or empty check’, it costs you time and energy to make that translation happen. So here is a first suggestion to make it read easier:

public class MailServiceImpl implements MailService {

	public void sendMail(String from, String to, String subject, String message) {
		if (parametersAreNotNullOrEmpty(from, to, subject, message)) {
			// send the email
		}
	}

	private boolean parametersAreNotNullOrEmpty(String from, String to, String subject,
			String message) {
		return from != null && !"".equals(from) &&
			to != null && !"".equals(to) &&
			subject != null && !"".equals(subject) &&
			message != null && !"".equals(subject);
	}

}

When another developer is reading the sendMail method, he will now know that when the parametersAreNotNullOrEmpty the mail will be sent. It does not need any translation, the method name just says what it does! Simple! By doing this, you greatly reduce the needed brainpower to understand what is going on. The refactoring method used is called Extract method.

Reading code is sometimes easy for your brain to handle. Sometimes your brain seems to explode because of the complex statements and context you need to be aware of. It is strongly tied with the Cyclomatic Complexity, the Coupling between Objects (CBO) and the lack of Cohesion in your code. If you are using any tools to measure your code, like Sonar for example, look for these metrics to find code that needs attention. But it is always better to refactor while you have made the translation in your brain, if you see things can be written simpler to reduce the needed brainpower, by all means do so. Not giving software the appropriate attention might let your code rot. Small refactorings help you prevent that.

I hope you have seen a bit of the power of small refactorings. I will get back to them in my future posts as I will post more concrete examples and how I would/have dealt with them. To me, small refactorings need to be part of your system and are introduced when you do TDD. All too often when the code works, it is not looked at again. Making these small refactorings can make a big difference and take relatively no time.