Design by Contract vs. Test-Driven Development

May 28th, 2011

A great many years ago I was fascinated by Bertrand Meyer’s book “Object Oriented Program Construction.” One of the many remarkable things in that book is the idea of “Design By Contract”, where you specify what a method does by means of a logical pre– and post–condicion. Consider the square root function:

  pre: x ≥ 0
  post: abs(y*y - x) < epsilon

This is a very good specification:

  • It’s efficiently executable.
  • The intent is clear.
  • Gives no hint about how to implement it, i.e., it does not contain design ideas.

Now I’m reading the Scrumban book by Corey Ladas. One thing Corey says is that Test-Driven Development is good, but not as good as Design By Contract; in fact, he says, TDD might be a stepping stone to DBC.

Read the rest of this entry »

Feeling like carrying bags of sand

May 22nd, 2011

A dreary afternoon

A while ago I was in the office, while the team was busy programming. I heard one of the developers typing with some intensity, and puffing. “What are you working on?” — I asked. — “I’m working on this administration panel. And it’s darned tiresome work!!”

So I started observing him. Read the rest of this entry »

The real meaning of “Technical Debt”

May 18th, 2011

Ron Jeffries on the Software Craftmanship mailing list recently wrote this:

We write a test showing what we intend to accomplish, and a few
minutes later, we have accomplished it. If doing that has made the
design not quite as nice as it was before we started, we evolve the
design in place to keep it good.

The more we practice this, the easier it gets and the better we get
at it.

That said, there will always be times when our design ideas come too
late for immediate inclusion but they are still desirable to put
into the program. This is the original meaning of “technical debt”,
the deviation of the code now from what we understand of the
desirable design now.

I find it very clear… this explains that “technical debt” does not mean “code like hell, make a mess, hope for the best, we’ll fix it later…”. It means that, assuming I always write clean code, which means write as good code as I can, it can happen that I get an idea about how the code *should have been* organized. That may take days to do, so I don’t do it at once. It remains as a “debt” I will pay some day.

This also means that design debt is not immediately visible! It’s in the mind of people who worked for months with a project and finally got an insight. The kind of refactorings I suggested earlier might be an example of technical debt.

Anti-FOR tips from the Yahtzee Kata

May 14th, 2011

Again on the Kata Yahtzee, that I blogged about some time ago.

If you have not solved the kata at least once, please stop reading this! Get back when you have.


*         *
*

Good to see you again! Now that you solved it, you probably know that the naive solution takes many “for” loops. Let D be the player dice, represented as an array of die results, e.g., D=(1,6,1,6,4). The naive rules for sixes would be

    def sixes_score 
      sum = 0
      for d in D
        if d == 6
          sum += 6
        end
      end
      return sum
    end
  

This solution involves searching for sixes and adding up. Why do we need to search? We need to search because there are many different D that are worth exactly the same for the sixes rule. For instance, both D=(1,2,3,6,6) and D=(6,6,1,2,3) are worth 12.

Read the rest of this entry »

Accit 2011 (Agile Coach Camp Italy) report

May 14th, 2011

Some notes on what I took home from the Agile Coach Camp Italy 2011, that happened in a beautiful country resort in Umbria from 6 to 8 May.

The session “What is a coach” facilitated by Andrea Provaglio, for a sampling of how coaches think and what they do.

The session on “Agile ceremonies in distributed teams”, facilitated by Sven Tiffe, for tips and real-life tales.

The session “Coaching Dojo”, facilitated by Oana Juncu, where novice coaches practice problem solving by asking questions.

The session about ALE Italy, again by Andrea, where we shared ideas and vision about a shared idea of Agile and Lean in Europe. In particular the idea of sharing “Status of Agile in my Country” reports.

The session about Conceptualizations by Pierluigi Pugliese, that introduced some strategic-level models for deciding how and if to introduce change in an organization.

The session about “A3 Thinking” by Claudio Perrone, showing that problem solving is a structured activity that can be taught and learned.

The session “Becoming a Coach”, organized by Vittorio Scibetta, where accomplished coaches shared their thoughts on things that shaped their coaching and how to learn about coaching.

The coding dojo where Alberto Brandolini practiced the art of maintaining focus while a chattering crowd of “umarell” (*) was teasing and criticizing him!

Now it’s clear to me that being an agile coach involves more than knowing TDD. If you want to be an “agile coach”, there’s a lot to learn about the “coach” part in addition to the “agile” part.

This was the first “unconference” I attended. In this kind of conference, also known as an “open space”, the program is not prepared beforehand; rather, the organizers provide a structure, such as blank timetables, rooms and materials, and by a process called “marketplace” the participants prepare the program on the spot. It was great! I learned so much. In this case the openspace organizer was Pierluigi, who spent a lot of care and attention to detail to make it work smoothly.

I also was impressed by the good energy of participants; lots of games, laughs and smiles. It’s been a very good place to be.

(*) In Bologna, “umarell” is someone with time on his hands who watches workers in roadworks and offers criticism :-)

Intervento al Novara-XPUG

April 12th, 2011

Lunedì 18 aprile sono invitato dagli amici del Novara XPUG per una presentazione. Parlerò di “planning patterns and antipatterns”, una presentazione che ho proposto anche a Better Software 2011 e che conto di rodare in questa occasione :o)

Le informazioni sono su www.gallug.it . L’indirizzo è

Viale Beato Quagliotti, 1
28066 – Galliate (NO) – Italy

We don’t have time for tests

March 26th, 2011

At lunch I had the familiar conversation about how TDD/pairing are fine unless you’re under pressure to deliver, and then …. you just do whatever it takes. Well, if you don’t think TDD/pairing are “what it takes,” then why do you /ever/ work that way?
Dave Nicolette

Same thing here. I was talking with a potential customer the other day and he said “for most projects here we don’t have time to write tests, we just code like hell to get them finished as soon as we can”. Well, but writing tests, for me, *is* the way to get it finished as soon as I can. The moment when we’re under pressure is the moment we should stick to good technique the most.

One example of this is a nice coding competition by Lasse Koskela and Markus Hjort at XP Days Benelux 2006. The objective of the game was to write a program to play Indian Poker (a silly, fun version of Poker) and win against other programs. The whole competition lasted less than three hours. As you can imagine there was not much time to waste :-) So what did we do? (I was pairing with a young chap from Philips who didn’t know much Java, so I, well, kept the keyboard all the time.) As I mentioned in my earlier report on the event, We wrote an acceptance test and then we used TDD. We did drive *all* code with tests. And we won :-)

How did we win? Well, for one thing, half the other programs crashed. Ours didn’t. We decided on a simple strategy to decide when to “stay” and when to “fold”. Since we finished early and we still had something like 10 minutes, we decided to add an option of raising if the cards looked very good for us. Still driving code with tests. And you know what? At the last round only two or three programs remained. Our bot won by raising!

Three hours, a new API, a new problem. I did what it takes: to use the best programming technique I know. I don’t have time for working in a sloppy way.

David Tchepak on TDD

March 25th, 2011

David Tchepak wrote a thoughtful post on TDD. I share what he says. I find useful this little summary:

The process of writing the test gives us all sorts of feedback.

  • The setup is too long or complicated? We’ve probably got too many collaborators (or are violating the Law of Demeter for them) and can try encapsulating them behind a new abstraction.
  • Too many scenarios or test fixtures on the same SUT? Our SUT probably has too many responsibilities.
  • Too hard to isolate the behaviour we’re trying to test, or can’t find how to write an assert for the behaviour? Maybe the current API or abstraction is wrong, and needs to be broken down differently?

[…] Writing the test first gives us ample opportunity to respond to this feedback, to sketch out our design, before committing to it. There is no cheaper time to change your code than before it is written.

The article is full of little gems like this note:

If you can’t get TDD to help you with a problem, make a note of it before trying something else, and come back to it later. It is important to see if it was just a problem TDD was ill-suited for, or whether a gap in your knowledge has been exposed. You’ll never know the difference if you give up too easily on TDD. Pursuing these leads is what led me to discover mocking, IoC containers, conventions, BDD etc. And I’m far from finished finding gaps in my knowledge. ;)

I like this tone. He does admit that TDD will not always for us, yet he advises not to accept that as a fact. Every obstacle in our work should be a reason to sit down and think what we could have done differently. Just as a team should not accept bugs as an inevitable fact of life, but should treat each one as an indication that they must do something to improve their process, the same should apply to when we are “stuck” not knowing how to proceed, or when we don’t like how our code turned out to be. Think about it; what part in our process could have been improved so that this does not happen again? (And if this leads me to think “my process? what process??”, great! I’m on the right path to improve :-)

Algebraic datatypes in Java

March 10th, 2011

Being in bed with a little fever, I thought it might be a good time for a little easy work on functional programming in Java.

Haskell envy

One of the things functional programmers often use is algebraic datatypes. For instance, in Haskell you would define a binary tree as such:

type tree = Empty
          | Leaf of int
          | Node of tree * tree
  

This says that a tree is either the Empty tree, or a Leaf that carries an integer value, or a Node that carries two subtrees.

The next thing is to define functions, such as tree height; the nice thing is that the functions are then defined by cases. It’s kind of fun:

height :: Tree -> Int
height Empty = 0
height (Leaf n) = 1
height (Node l r) = 1 + max (height l) (height r)    
  

This says that an Empty tree has height 0, a Leaf has height 1, and a Node has height that is the maximum height of its subtrees, plus 1. Now we could have fun defining all sorts of other functions, like the contour (the list of the integers of all leafs), search for a particular value, addition of elements, and so on.

Additionally, when working in languages like Haskell, the compiler makes sure that when we define a function by cases, the program will not compile unless we remembered to define all cases.

This sort of data structures have all sort of applications; an obvious one is representing syntax trees, that is the output of a parser. Another one is representing the syntax rules themselves.

We can do it!

What’s to do if you have to work in a simpler language like Java? Do we have to give up the fun of algebraic data types? Of course not! It’s possible to define such structures in Java, even though it will take one or two orders of magnitude more lines of code.

Step zero: define the structure

public abstract class Tree {}

public class EmptyTree extends Tree {}

public class Leaf extends Tree {
    public Leaf(int value) {
    }
}

public class Node extends Tree {
    public Node(Tree left, Tree right) {
    }
}    

Now we can create our trees with the following deliciously clumsy syntax:

Tree tree = new Node(
    new Node(new Leaf(0), new EmptyTree()), 
    new EmptyTree());    

We could make it slightly less verbose with static functions.

Step one: define height

The easy way to add a function is to define it abstractly in Tree. The compiler then forces us to define it in all Tree subclasses (in all cases). First a test:

@Test
public void heightOfSimpleTree() throws Exception {     
    Tree tree = new Node(
        new Node(new Leaf(0), new EmptyTree()),
        new EmptyTree());
    assertEquals(3, tree.height());
}

Then the implementation:

public abstract class Tree {
    public abstract int height();
}


public class EmptyTree extends Tree {
    public int height() {
        return 0;
    }
}    


public class Leaf extends Tree {
    public Leaf(int value) {
    }

    public int height() {
        return 1;
    }
}


public class Node extends Tree {
    private final Tree left;
    private final Tree right;

    public Node(Tree left, Tree right) {
        this.left = left;
        this.right = right;
    }

    public int height() {
        return 1+ Math.max(left.height(), right.height());
    }
}

(I told you this was going to be verbose. You were warned :-)

Step two: respect the OCP, son!

Now we could go on defining all kinds of functions on trees this way; but this would mean that for every new function, we need to change all of our classes. That won’t do; we don’t want to keep changing and adding to the same old files. We want to close the Tree classes for modification, but keep them open for extension; this is the open/closed principle. What can we do?

A pattern to the rescue. Have you ever wondered where it’s reasonable to use Visitor? Well, this is it. As usual, we start with a test:

@Test
public void heightWithVisitor() throws Exception {
    Tree tree = new Node(
        new Node(new Leaf(0), new EmptyTree()),
        new EmptyTree());
    Visitor height = new Height();
    assertEquals(3, tree.accept(height));
}

The implementation of visitor can be:

public abstract class Tree {
    public abstract int accept(Visitor visitor);
}

public class EmptyTree extends Tree {
    public int accept(Visitor visitor) {
        return visitor.visitEmptyTree();
    }
}

public class Leaf extends Tree {
    private final int value;

    public Leaf(int value) {
        this.value = value;
    }

    public int accept(Visitor visitor) {
        return visitor.visitLeaf(value);
    }
}

public class Node extends Tree {
    private final Tree left;
    private final Tree right;

    public Node(Tree left, Tree right) {
        this.left = left;
        this.right = right;
    }

    public int accept(Visitor visitor) {
        return visitor.visitNode(left, right);
    }
}

Note that each tree subcase provides the visitor with all the information they contain. This way we avoid getters, which is nice. The definition of Height is very similar to the Haskell example:

public class Height implements Visitor {    
    public int visitEmptyTree() {
        return 0;
    }

    public int visitLeaf(int value) {
        return 1;
    }

    public int visitNode(Tree left, Tree right) {
        return 1 + Math.max(left.accept(this), right.accept(this));
    }
}

The nice thing is that now the Height function lives in its own little object. We were able to decouple it from the Tree classes.

We still can’t forget to define a case, as the compiler will force us to implement all three methods of Visitor.

Step three: generics

Of course, the big problem with this Visitor implementation is that it only works for functions that return integers. We can solve this with Java generics:

public interface Visitor<T> {
    T visitEmptyTree();
    T visitLeaf(int value);
    T visitNode(Tree left, Tree right);
}

public abstract class Tree {
    public abstract <T> T accept(Visitor<T> visitor);
}

public class EmptyTree extends Tree {
    public <T> T accept(Visitor<T> visitor) {
        return visitor.visitEmptyTree();
    }
}
// etc.

The other way to solve the genericity problem would be to define the Height visitor as a stateful object, that has a int result() method that is not part of the Visitor interface. But we’ll leave that to some other time.

A delightful little book on this very subject is A Little Java, A Few Patterns by Matthias Felleisen and Daniel P. Friedman. In fact I think I learned the meaning of Visitor by reading this book! The authors wrote a number of books on Lisp and Scheme in a similar vein; the first one was The Little Lisper and it takes a very unusual approach to teaching.

Hope it comes in handy!

Last presentation: TDD from end to end

March 6th, 2011

Yesterday I presented “TDD from end to end” at Codemotion in Rome. My talk was about how to use TDD to drive the development of the whole system, from the GUI to the database. The slides contain a small solved exercise, which could be a good kata for Java servlet and JDBC skills. The techniques I showed are not my own! I’m showing things I learned from Francesco Cirillo and Carlo Bottiglieri.

The slides are in Italian, but they mostly contain Java code with English identifiers: 20110305-tdd-codemotion.pdf. Enjoy!

Update: here is the video.