Coding Dojo – Top-Down oder Bottom-Up

Ziel des letzten DOJOs war die Implementierung von Game Of Life. Auch wenn immer versucht wurde bis Ende des DOJOs eine lauffähige Version zu bekommen, so stand das Software Design und die korrekte Methodik (e.g. TDD) im Vordergrund. Es ist für einen Entwickler oft schwer sich zu bremsen und auf die korrekte Ausführung zu achten – daher empfinde ich es als gute Übung.

Die Implementierung erfolgte in 10 Minuten Pair Programming Sessions auf einem Laptop, sodass jeder Teilnehmer mit “Entscheidungen” anderer Teilnehmer arbeiten musste.

Interessant war für mich auf jeden Fall, dass zwei Strategien aufeinander prallten:

  • Top-Down: Von den 4 Regeln weg implementieren
  • Bottom-Up: Grundstrukturen schaffen (e.g. Board, Cell) und sich nach oben hin durcharbeiten

In diesem einfachen Beispiel war Bottom-Up noch relativ gut möglich, wenngleich e.g. Methoden implementiert wurden wie „AreAllCellsDead“. Braucht man die Methode schlussendlich? Ein Argument war, dass man sie ja wieder löschen kann – mit TDD ist aber wertvolle Zeit verloren gegangen, weil Tests unnötig implementiert wurden. Ebenfalls würde sich das Interface des Boards unnötig verkomplizieren.

Der Top-Down Approach wäre zuerst sich die API zu überlegen, Top-Level Tests zu schreiben und anschließend kleinere Teile zu implementieren.

currentEvolutionBoard.ForAllCells(
    (cell, nextEvolutionBoard) =>
    {
        // Any live cell with fewer than two live neighbours dies, as if caused by under-population.
        if (cell.IsAlive() && cell.AmountOfNeighbours() < 2)
        {
            nextEvolutionBoard.CopyCellFromTemplate(cell).Dies();
        }

        // Any live cell with two or three live neighbours lives on to the next generation.
        if (cell.IsAlive() && (cell.AmountOfNeighbours() == 2 || cell.AmountOfNeighbours() == 3))
        {
            nextEvolutionBoard.CopyCellFromTemplate(cell);
        }

        // Any live cell with more than three live neighbours dies, as if by over-population.
        if (cell.IsAlive() && cell.AmountOfNeighbours() > 3)
        {
            nextEvolutionBoard.CopyCellFromTemplate(cell).Dies();
        }

        // Any dead cell with exactly three live neighbours becomes a live cell, as if by reproduction.
        if (cell.IsDead() && cell.AmountOfNeighbours() == 3)
        {
            nextEvolutionBoard.CopyCellFromTemplate(cell).Reproduction();
        }
    });

Welche Methode zielführender ist, ist allgemein schwer zu sagen. Ich habe allerdings die Erfahrung gemacht, dass die Verlockung des Over-Engineerings bei Bottom-Up relativ groß ist.