At the Lyon Coding Dojo Meetup, we did the Island Kata.

Mob Programming

As is usual now and since we are few enough, we used mob programming to work together. Mob programming is quite enjoyable, fast and allows for a lot of knowledge sharing. It also has the advantage of not going in the wrong direction as there is always someone to prevent it.

Mob Programming

The kata

In this kata, islands, containing resources are to be compared to one another. The goal is to list the top islands indexes, indexes referring to the order of their input. The input consists of lines, one for each island, and on each line, there is a list of quantities for each indexed resource separated by spaces. Islands are to be compared using the weighed product model given that each resource has its own priority.

First discussion

We first agreed that we should not bother ourselves with parsing or printing output and that we'd better dedicate our time to inner workings. Detroit-style TDD works by testing state rather than behavior. If we had external systems like stdout, we would have to mock the stdout and verify that it was called with the right parameters. So in order to test state, we should have a method returning out of two islands, which one has the most resources.

Our goal for this kata was to use a stream-like approach using Java.

Baby steps

We've grown accustomed to using baby steps in our usage of TDD. This means that we write a very simple test, to begin with, simplifying the business case. We started comparing two islands with only one resource each. The weighed product model has no real interest in this case, so comparing the island's quantities is enough to make the test green.

public void islandsWithOneResourceShouldBeSortedByResource() {
  Island islandA = new Island(new Resource(1));
  Island islandB = new Island(new Resource(2));
  Island bestIsland = Island.best(islandA,islandB);
  assertThat(bestIsland).isEqualTo(islandB);
}

We continued with a second resource and this is where we really introduced the weighed product model.

public void islandsWithTwoResourceShouldBeSortedByResource() {
  Island islandA = new Island(new Resource(1), new Resource(2));
  Island islandB = new Island(new Resource(2), new Resource(3));
  Island bestIsland = Island.best(islandA,islandB);
  assertThat(bestIsland).isEqualTo(islandB);
}

We then added a varargs constructor to Islands, even though the number of resources is equal to 10 in the kata.

In order to have a more functional, stream-based implementation, we used that varargs as a source for our stream, calculated the individual weighed products of our resources and then reduced them.

Instead of streaming on resources, comparing each island's resources, we looped on one island, comparing it with the other. This is mainly because the resource priority was part of the Island class. Had we separated that notion, we could have streamed differently.

Problems we came across

At this stage, several pain points arose:

  • too much refactoring
  • no clear design separation: resource priorities were a part of the Island class for example
  • bad naming strategy (not aligned with domain terminology)
  • slow down in pace
  • doubt in our implementation

Analysis

This is basically due to our approach to the kata. We were given a domain problem with input and expected output. This is much like an acceptance test. We probably should have written down this acceptance test, to begin with, and made the design around that.

TLDR;

I'm not saying inside-out TDD isn't good, but for overall design, it's better to start with the big picture, as it helps to provide a cohesive domain design, whereas inside-out TDD is great for focusing on the class level and to maintain a single responsibility upon classes.

For next time

I wasn't able to attend the next kata but this one was naturally more focused on outside-in TDD.