# Bowling Game Kata von Uncle Bob



## looparda (26. Okt 2020)

Ich bin auf das Bowling Game Kata von Uncle Bob gestoßen aus dem Hintergrund besser den TDD-Workflow zu verinnerlichen. Mir geht es da um die PPT, die auf der Seite zum Download steht und das Problem beschreibt, Anforderungen vorgibt und exemplarisch eine TDD Lösung erarbeitet.

Am Anfang der PPT (Folien 4-9) wird ein objektorientiertes Design vorgestellt und ich wurde hierdurch gedanklich ziemlich darauf vorbereitet nun testgetrieben, Stück für Stück, am Ende bei dieser Lösung zu landen. In mir fing es schon zu denken an: "Ich werde die Frames als Klassen abbilden. Ein Frame muss zur Berechnung des Scores für Spare und Strike jedoch seinen Nachfolger kennen... ich werde wohl eine verkettete Liste benötigen..". Ich hab mich jedoch gezügelt und darauf besonnen, dass man mit TDD nichts überstürzt. Ich hab mir also nichts weiter dabei gedacht versucht das Kata eigenständig zu lösen und mit der PPT abzugleichen. Hat Es hat Spaß gemacht und ich war verwundert wie einfach man zu den Algorithmen gekommen ist, wie lesbar der Code ist und wie elegant es gelöst ist. 

Folgende Aspekte beschäftigen mich dazu: 
1. Offen gelassen hat die PPT das am Anfang vorgestellte objektorientierte Design. Ist das jetzt der finale Code? Was ist mit den Klassen? Komme ich mit TDD gar nicht zu dem objektorientierten Design?
2. Wenn ich TDD mal wieder vergesse und es "klassisch" löse, also nach dem vorgestellten objektorientierten Design, dann lande ich bei einer Lösung die nicht annähernd so elegant und einfach ist.

Ich habe keine konkreten Fragen dazu. Vielleicht kann jemand die Gedanken nachvollziehen und seine Sichtweise dazu beschreiben.


----------



## mrBrown (26. Okt 2020)

Cool, dass du das gemacht hast, magst du den Code mal zeigen? 



looparda hat gesagt.:


> Offen gelassen hat die PPT das am Anfang vorgestellte objektorientierte Design. Ist das jetzt der finale Code? Was ist mit den Klassen?


Ich verstehe das zu Anfang zur als Beispiel, wie man es auf dem Weg angehen würde – umgesetzt wird es dann aber anders. ...



looparda hat gesagt.:


> Komme ich mit TDD gar nicht zu dem objektorientierten Design?



... Generell kommt man aber auch mit TDD zu einem OO-Entwurf, wenn man konsequent refactored und es sich eben anbietet.
Hier zB könnte man das int-Array zu einem Frame-Array refactoren, allerdings hat das eben auch Nachteile, weil man gar nicht so sehr den Zugriff auf ein Frame, sondern auch den auf einzelne Rolls braucht, und mit einer Frame-Klasse macht man es sich uU nur komplizierter.
In dem Pfadsuche-Beispiel von mir ist Refactoring nicht zu Ende gebracht, aber potentiell würde man noch zB Node, Path, Graph einführen, die jeweils bestehende Funktionalität besser kapseln und nutzbar machen (zB String -> Node, List<Edge> -> Path (mit Edges und Länge), alle Nodes und Edges gekapselt in einem Graph).


----------



## looparda (26. Okt 2020)

mrBrown hat gesagt.:


> Cool, dass du das gemacht hast, magst du den Code mal zeigen?


Ich hab mich an das Beispiel gehalten, um mir die Vorgehensweise anzueignen und daher ist mein Code sehr nahe an dem aus der PPT:

```
public class Game {
  private int rolls[] = new int[21];
  private int currentRoll = 0;

  public void roll(int pins) {
    rolls[currentRoll++] = pins;
  }

  public int score() {
    int score = 0;
    int frameIndex = 0;
    for (int frame = 0; frame < 10; frame++) {
      if (isStrike(frameIndex)) {
        score += 10 + strikeBonus(frameIndex);
        frameIndex++;
      } else if (isSpare(frameIndex)) {
        score += 10 + spareBonus(frameIndex);
        frameIndex += 2;
      } else {
        score += sumOfBallsInFrame(frameIndex);
        frameIndex += 2;
      }
    }
    return score;
  }

  private boolean isStrike(int frameIndex) {
    return rolls[frameIndex] == 10;
  }

  private int sumOfBallsInFrame(int frameIndex) {
    return rolls[frameIndex] + rolls[frameIndex+1];
  }

  private int spareBonus(int frameIndex) {
    return rolls[frameIndex+2];
  }

  private int strikeBonus(int frameIndex) {
    return rolls[frameIndex+1] + rolls[frameIndex+2];
  }

  private boolean isSpare(int frameIndex) {
    return rolls[frameIndex]+rolls[frameIndex+1] == 10;
  }
}
```


----------

