Thomas Sundberg

November 29, 2011

The simplest possible solution

Filed under: Agile, Clean Code, Java, Programming, Software Craftsmanship, TDD, Teaching — Tags: , — Thomas Sundberg @ 22:02

The simplest possible solution that could work. Ever heard that expression? What does it mean? Really?

The answer is obviously something that in a really simple way satisfies the test you currently are working on. Nothing more, nothing less.

Let me walk you through an example so I can show you what I mean. This is the beginning of my world domination computer system. Some people may call it a simple calculator. I will test drive it and build in small increments.

Test driving it means that I will write the tests before I write any production code. I never add any production code if I don’t have a test that tells me that I have to add it. I will never do any refactoring when I have failing tests. Refactoring can only be done when all tests passes.

The process can be described as

  • Write a failing test – red bar
  • Write the simplest possible solution that satisfies the test – green bar
  • Refactor
  • Repeat until done

It is sometimes called red-green-refactor. The expected cycle time is on the minute scale and normally below 10. This is a fast cycle. You only take small steps.

Lets start with the first test. Add 1 and 1 and expect the result 2.

@Test
public void addOneAndOne() {
    Calculator calculator = new Calculator();

    int expected = 2;
    int actual = calculator.add(1, 1);

    assertThat(actual, is(expected));
}

The simplest possible solution is in my mind this:

public int add(int a, int b) {
    return 2;
}

I hard code the expected answer. I once did this at a code retreat and my programming partner said: “That’s cheating!” and was almost upset. I think hard coding the first value is ok if you do something about it as soon as possible. As soon as possible is when the next test fails and I know what to fix, normally within minutes. I actually claim that this is the preferred way to grove a system. I don’t want to build more production code then I have to, if there isn’t any reason for making a solution more general. I want to defer a general solution as long as possible and implement it only when there is a real need for it.

It can be argued that this solution isn’t safe for the future. It may even be considered to be incorrect. But if all we know is that we have the requirement to solve the simple add above, add 1 and 1, then I claim that this is a correct solution.

Adding another test may show us that we are incorrect. Let’s add 2 and 3 and expect the result 5.

@Test
public void addTwoAndThree() {
    Calculator calculator = new Calculator();

    int expected = 5;
    int actual = calculator.add(2, 3);

    assertThat(actual, is(expected));
}

It turns out, hardly surprising, that the test fails.

Ok, lets apply the simplest possible to this problem so we get a passing test.

public int add(int a, int b) {
    if (a == 1) {
        return 2;
    } else {
        return 5;
    }
}

This solution solves the problem. It may not be the smartest solution, but it does the job. We could of course continue with this approach until we have implemented all possible additions. Following that path may, however, not be very wise. It may even be the dumbest thing we could do.

The tests passes, we have green bar. Now we can apply some refactoring if we think there is anything we could do in a better way. An obvious refactoring is of course this one:

public int add(int a, int b) {
    return a + b;
}

All tests passes and we have done some refactoring that may have done this solution generic and future safe. We can stop here.

Why didn’t I just apply the last solution from the beginning? The answer if of course that I wanted to show you how I think when I build something. I always try to use really small, safe steps. Many small, safe steps later I usually have a system that works correctly.

It is always easier to solve a small problem compared to solve a large problem. It is also always better to be safe then sorry. So small and safe is my motto.

Generally applicable?

Can this always be applied? Or does it exist situations where small steps are impossible? I have been a developer for more then twenty years by now. I have still not found a system where small steps are impossible. Small steps are often hard since you have to divide a large problem to smaller parts. But there is a big difference between hard and impossible.

I have seen many systems where developers regularly take very large steps. They often claim that their system is so special that small steps are not possible to apply. They also tend to claim that small steps are to slow. When they take large steps, they often struggle to get whatever they are working even to compile. I have seen examples where it has taken days to get things to compile. These developers are very seldom using test driven development

My conclusion is that small and safe steps are always possible. I also think that many developers are either

  • afraid to leave their comfort zone
  • to lazy to try
  • to stressed to consider working in a more efficient way
  • not skilled enough to understand this

Some of the issues above can be addressed by showing them good examples. Laziness is hard to deal with, force is seldom a good solution. Stress is sometimes a matter of personality, personality is also hard to address. Stress can also be addressed by management by understanding that it takes time to do the job properly. Skill is something you can gain by working on it. Leaving your comfort zone will most likely give you skill if you give it a fair chance.

Inspiration

Inspiration to this blog came from a conversation with a colleague at an airport in Ukraine where he looked a bit skeptic when I claimed that it is always ok to hard code a solution. Given that you don’t leave it there if you have reasons to suspect that there are tests that will reveal that this hardcoded solution isn’t good enough.

Thank you Ari for the inspiration!

Acknowledgements

This post has been reviewed by some people who I wish to thank for their help

  • Malin Ekholm
  • Johan Karlsson

Thank you very much for your feedback!

Resources

About these ads

2 Comments »

  1. I’m a project manager with a programming background… And my question to you, what’s the point of creating a function that always returns a static number?

    Comment by PM Hut — December 1, 2011 @ 09:34

    • There may be at least two reasons.

      One being documentation. We want to avoid spreading magic numbers in the codebase.

      Another is as a starting point for something that may become a complicated calculation. The answer for one specific situation may be the hardcoded number in the first iteration over the problem. The next time we we iterate over the problem, we may find that the static number isn’t sufficient and add some calculation. When adding the calculation we use the safety net from the first test to verify that we didn’t break anything. Hardcoding in this situation is the first step towards a general solution. If we need a general solution. I would expect the time between the first and second iteration to be measured on the second scale or the minute scale if we can determine early that a hardcoded value isn’t enough.

      The point here is small and safe steps. It is easier to solve a small problem then solving a large problem. Large problems can always be divided into many smaller problems. A hardcoded number is a smaller problem then getting a complicated calculation right.

      Comment by Thomas Sundberg — December 1, 2011 @ 09:50


RSS feed for comments on this post. TrackBack URI

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

The Silver is the New Black Theme. Create a free website or blog at WordPress.com.

Follow

Get every new post delivered to your Inbox.

Join 53 other followers

%d bloggers like this: