Dieser Artikel wurde verfasst, um TDD anzugehen und ein wesentliches Bild von TDD mit anderen zu teilen.
Entwurfs- / Analysetechnik, keine Testtechnik
--Wert
――Um etwas Wertvolles so effizient wie möglich zu machen ――Wenn Sie das Entwicklungsziel besser verstehen, desto korrekter können Sie Entscheidungen treffen. ――Ich werde mich erst entscheiden, wenn ich die richtige Entscheidung treffen kann, was ich treffen soll ――Wir entwickeln uns schrittweise aus den minimal erforderlichen Funktionen heraus und entwickeln das Design selbst schrittweise weiter
Geeigneter Fall: Agil ・ Ich weiß nicht, was ich machen möchte ・ Das Entwicklungsteam versteht das Entwicklungsziel nicht vollständig ・ Das Entwicklungsziel ist kompliziert und niemand kennt das richtige Design
--Rot: Schreiben Sie einen Test, der fehlschlägt (Hinzufügen von Funktionen / Hinzufügen von Bedingungen / Reproduktion von Fehlern usw.)
Wenn wir den obigen Zyklus durchlaufen, werden wir schrittweise basierend auf Rhythmus, Vertrauen und Vertrauen entwerfen.
Betreff: Berechnung der Bowling-Punktzahl Nutzungsumgebung: --IntelliJ Community-Version
Der erste Test, der hinzugefügt werden muss, besteht darin, einen "Nichtstun-Test" zu schreiben.
Red
import static org.assertj.core.api.Assertions.assertThat;
import org.junit.jupiter.api.Test;
public class BowlingGameTest {
@Test
public void test_all_Garter() {
var game = new BowlingGame();
assertThat(game).isNotNull();
}
}
Green
Klasse hinzufügen
public class BowlingGame {
}
Red
Machen Sie es zu einem Testfall für alle Wurfstrumpfbänder
import static org.assertj.core.api.Assertions.assertThat;
import org.junit.jupiter.api.Test;
public class BowlingGameTest {
@Test
public void test_all_Garter() {
var game = new BowlingGame();
+ for(int count = 0; count < 20; count++) {
+ game.recordOneShot(0);
+ }
- assertThat(game).isNotNull();
+ assertThat(game.getTotalScore()).isEqualTo(0);
}
}
Green
public class BowlingGame {
+ public void recordOneShot(int pins) {
+ }
+ public int score() {
+ return 0;
+ }
}
Red
import static org.assertj.core.api.Assertions.assertThat;
import org.junit.jupiter.api.Test;
public class BowlingGameTest {
// ry
+ @Test
+ public void test_all_one_pin() {
+ var game = new BowlingGame();
+ for (int count = 0; count < 20; count++) {
+ game.recordOneShot(1);
+ }
+ assertThat(game.score()).isEqualTo(20);
+ }
}
Green
public class BowlingGame {
private int totalScore = 0;
+ public void recordOneShot(int pins) {
+ totalScore += pins;
+ }
+ public int getTotalScore() {
+ return totalScore;
+ }
}
Ausgelöst durch den "unheimlichen Geruch" des Codes
//Testcode-Refactor (Entfernung von doppeltem Code: Methodenextraktion)
import static org.assertj.core.api.Assertions.assertThat;
+import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Test;
public class BowlingGameTest {
+ private BowlingGame game;
+
+ @BeforeEach
+ public void setup() {
+ game = new BowlingGame();
+ }
@Test
public void test_test_all_Garter() {
- var game = new BowlingGame();
- for(int count = 0; count < 20; count++) {
- game.recordOneShot(0);
- }
+ recordSamePinsManyShot(20, 0);
assertThat(game.getTotalScore()).isEqualTo(0);
}
@Test
public void test_all_one_pin() {
- var game = new BowlingGame();
- for (int count = 0; count < 20; count++) {
- game.recordOneShot(1);
- }
+ recordSamePinsManyShot(20, 1);
assertThat(game.getTotalScore()).isEqualTo(20);
}
+ private void recordSamePinsManyShot(int shotCount, int pins) {
+ for (int count = 0; count < shotCount; count++) {
+ game.recordOneShot(pins);
+ }
+ }
}
Red
import static org.assertj.core.api.Assertions.assertThat;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
public class BowlingGameTest {
private BowlingGame game;
@BeforeEach
public void setup() {
game = new BowlingGame();
}
// ry
+ @Test
+ public void test_spare() {
+ game.recordOneShot(4);
+ game.recordOneShot(6); //Ersatz 10+5=15
+ game.recordOneShot(5);
+ recordSamePinsManyShot(17, 0);
+ assertThat(game.getTotalScore()).isEqualTo(20);
+ }
private void recordSamePinsManyShot(int shotCount, int pins) {
for (int count = 0; count < shotCount; count++) {
game.recordOneShot(pins);
}
}
}
Überlegen Sie, wie Sie das Problem beheben können
Über die Ursache nachdenken → Weil ich mich nicht an den vorherigen Wurfzustand erinnere
Überlegen Sie sich eine Problemumgehung → Bereiten Sie ein Ersatzflag vor
Denken Sie über das Verfahren nach --Zusatz der Ersatzflagge --Gesamtpunkte sind 10 Punkte → Flag ist eingeschaltet. Wenn Flag eingeschaltet ist, fügen Sie hinzu
↓ Versuchen Sie zu beheben
public class BowlingGame {
private int totalScore = 0;
+ private boolean isSpare = false;
public void recordOneShot(int pins) {
totalScore += pins;
+ if (isSpare) {
+ totalScore += pins;
+ isSpare = false;
+ }
+ if (totalScore == 10) {
+ isSpare = true;
+ }
}
public int getTotalScore() {
return totalScore;
}
}
package bowling;
public class BowlingGame {
private int totalScore = 0;
private boolean isSpare = false;
+ private int beforePins = 0;
public void recordOneShot(int pins) {
totalScore += pins;
if (isSpare) {
totalScore += pins;
isSpare = false;
}
- if (totalScore == 10) {
+ if (pins + beforePins == 10) {
isSpare = true;
}
+ beforePins = pins;
}
public int getTotalScore() {
return totalScore;
}
}
Red
import static org.assertj.core.api.Assertions.assertThat;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
public class BowlingGameTest {
private BowlingGame game;
@BeforeEach
public void setup() {
game = new BowlingGame();
}
// ry
+ @Test
+ public void test_not_spare_when_before_and_current_total_10() {
+ game.recordOneShot(2);
+ game.recordOneShot(6);
+ game.recordOneShot(4);
+ game.recordOneShot(7);
+ recordSamePinsManyShot(16, 0);
+ assertThat(game.getTotalScore()).isEqualTo(19);
+ }
private void recordSamePinsManyShot(int shotCount, int pins) {
for (int count = 0; count < shotCount; count++) {
game.recordOneShot(pins);
}
}
}
Green
public class BowlingGame {
private int totalScore = 0;
private boolean isSpare = false;
private int beforePins = 0;
private int shotCount = 1;
public void recordOneShot(int pins) {
totalScore += pins;
if (isSpare) {
totalScore += pins;
isSpare = false;
}
- if (pins + beforePins == 10) {
+ if (shotCount == 2 && pins + beforePins == 10) {
isSpare = true;
}
beforePins = pins;
+ shotCount = shotCount == 1 ? 2 : 1;
}
public int getTotalScore() {
return totalScore;
}
}
Red
import static org.assertj.core.api.Assertions.assertThat;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
public class BowlingGameTest {
private BowlingGame game;
@BeforeEach
public void setup() {
game = new BowlingGame();
}
// ry
+ @Test
+ public void test_strike() {
+ game.recordOneShot(10);
+ game.recordOneShot(3);
+ game.recordOneShot(4);
+ game.recordOneShot(2);
+ recordSamePinsManyShot(15, 0);
+ assertThat(game.getTotalScore()).isEqualTo(26);
+ }
private void recordSamePinsManyShot(int shotCount, int pins) {
for (int count = 0; count < shotCount; count++) {
game.recordOneShot(pins);
}
}
}
--Fest
Green
public class BowlingGame {
private int totalScore = 0;
private boolean isSpare = false;
private int beforePins = 0;
private int shotCount = 1;
+ private int strikeAddScoreCount = 0;
public void recordOneShot(int pins) {
totalScore += pins;
if (isSpare) {
totalScore += pins;
isSpare = false;
}
if (shotCount == 2 && pins + beforePins == 10) {
isSpare = true;
}
+ if (strikeAddScoreCount > 0) {
+ totalScore += pins;
+ strikeAddScoreCount -= 1;
+ }
+ if (pins == 10) {
+ strikeAddScoreCount = 2;
+ }
beforePins = pins;
shotCount = shotCount == 1 ? 2 : 1;
}
public int getTotalScore() {
return totalScore;
}
}
Methodenextraktion
package bowling;
public class BowlingGame {
private int totalScore = 0;
private boolean isSpare = false;
private int beforePins = 0;
private int shotCount = 1;
private int strikeAddScoreCount = 0;
public void recordOneShot(int pins) {
totalScore += pins;
- if (isSpare) {
- totalScore += pins;
- isSpare = false;
- }
- if (shotCount == 2 && pins + beforePins == 10) {
- isSpare = true;
- }
-
- if (strikeAddScoreCount > 0) {
- totalScore += pins;
- strikeAddScoreCount -= 1;
- }
- if (pins == 10) {
- strikeAddScoreCount = 2;
- }
+ calcSpareAddScore(pins);
+ calcStrikeAddScore(pins);
beforePins = pins;
shotCount = shotCount == 1 ? 2 : 1;
}
+ public int getTotalScore() {
+ return totalScore;
+ }
+
+ private void calcSpareAddScore(int pins) {
+ if (isSpare) {
+ totalScore += pins;
+ isSpare = false;
+ }
+ if (shotCount == 2 && pins + beforePins == 10) {
+ isSpare = true;
+ }
+ }
+
+ private void calcStrikeAddScore(int pins) {
+ if (strikeAddScoreCount > 0) {
+ totalScore += pins;
+ strikeAddScoreCount -= 1;
+ }
+ if (pins == 10) {
+ strikeAddScoreCount = 2;
+ }
+ }
}
Red
import static org.assertj.core.api.Assertions.assertThat;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
public class BowlingGameTest {
private BowlingGame game;
@BeforeEach
public void setup() {
game = new BowlingGame();
}
// ry
+ @Test
+ public void test_strike_double() {
+ game.recordOneShot(10);
+ game.recordOneShot(10);
+ game.recordOneShot(4);
+ game.recordOneShot(2);
+ recordSamePinsManyShot(14, 0);
+ assertThat(game.getTotalScore()).isEqualTo(46);
+ }
private void recordSamePinsManyShot(int shotCount, int pins) {
for (int count = 0; count < shotCount; count++) {
game.recordOneShot(pins);
}
}
}
Green
public class BowlingGame {
private int totalScore = 0;
private boolean isSpare = false;
private int beforePins = 0;
private int shotCount = 1;
private int strikeAddScoreCount = 0;
+ private int doubleAddScoreCount = 0;
public void recordOneShot(int pins) {
totalScore += pins;
calcSpareAddScore(pins);
calcStrikeAddScore(pins);
beforePins = pins;
shotCount = shotCount == 1 ? 2 : 1;
}
public int getTotalScore() {
return totalScore;
}
private void calcSpareAddScore(int pins) {
if (isSpare) {
totalScore += pins;
isSpare = false;
}
if (shotCount == 2 && pins + beforePins == 10) {
isSpare = true;
}
}
private void calcStrikeAddScore(int pins) {
if (strikeAddScoreCount > 0) {
totalScore += pins;
strikeAddScoreCount -= 1;
}
+ if (doubleAddScoreCount > 0) {
+ totalScore += pins;
+ doubleAddScoreCount -= 1;
+ }
if (pins == 10) {
+ if (strikeAddScoreCount == 0) {
strikeAddScoreCount = 2;
+ } else {
+ doubleAddScoreCount = 2;
+ }
}
}
}
Green
import static org.assertj.core.api.Assertions.assertThat;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
public class BowlingGameTest {
private BowlingGame game;
@BeforeEach
public void setup() {
game = new BowlingGame();
}
// ry
+ @Test
+ public void test_strike_turkey() {
+ game.recordOneShot(10);
+ game.recordOneShot(10);
+ game.recordOneShot(10);
+ game.recordOneShot(4);
+ game.recordOneShot(2);
+ recordSamePinsManyShot(12, 0);
+ assertThat(game.getTotalScore()).isEqualTo(76);
+ }
private void recordSamePinsManyShot(int shotCount, int pins) {
for (int count = 0; count < shotCount; count++) {
game.recordOneShot(pins);
}
}
}
Red
import static org.assertj.core.api.Assertions.assertThat;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
public class BowlingGameTest {
private BowlingGame game;
@BeforeEach
public void setup() {
game = new BowlingGame();
}
// ry
+ @Test
+ public void test_strike_and_spare() {
+ game.recordOneShot(10);
+ game.recordOneShot(6);
+ game.recordOneShot(4);
+ game.recordOneShot(2);
+ recordSamePinsManyShot(15, 0);
+ assertThat(game.getTotalScore()).isEqualTo(34);
+ }
private void recordSamePinsManyShot(int shotCount, int pins) {
for (int count = 0; count < shotCount; count++) {
game.recordOneShot(pins);
}
}
}
Green
public class BowlingGame {
private int totalScore = 0;
private boolean isSpare = false;
private int beforePins = 0;
private int shotCount = 1;
private int strikeAddScoreCount = 0;
private int doubleAddScoreCount = 0;
public void recordOneShot(int pins) {
totalScore += pins;
calcSpareAddScore(pins);
calcStrikeAddScore(pins);
beforePins = pins;
- shotCount = shotCount == 1 ? 2 : 1;
+ shotCount = shotCount == 1 && strikeAddScoreCount < 2 ? 2 : 1;
}
public int getTotalScore() {
return totalScore;
}
private void calcSpareAddScore(int pins) {
if (isSpare) {
totalScore += pins;
isSpare = false;
}
if (shotCount == 2 && pins + beforePins == 10) {
isSpare = true;
}
}
private void calcStrikeAddScore(int pins) {
if (strikeAddScoreCount > 0) {
totalScore += pins;
strikeAddScoreCount -= 1;
}
if (doubleAddScoreCount > 0) {
totalScore += pins;
doubleAddScoreCount -= 1;
}
if (pins == 10) {
if (strikeAddScoreCount == 0) {
strikeAddScoreCount = 2;
} else {
doubleAddScoreCount = 2;
}
}
}
}
Red
import static org.assertj.core.api.Assertions.assertThat;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
public class BowlingGameTest {
private BowlingGame game;
@BeforeEach
public void setup() {
game = new BowlingGame();
}
// ry
+ @Test
+ public void test_strike_double_and_spare() {
+ game.recordOneShot(10);
+ game.recordOneShot(10);
+ game.recordOneShot(6);
+ game.recordOneShot(4);
+ game.recordOneShot(2);
+ recordSamePinsManyShot(13, 0);
+ assertThat(game.getTotalScore()).isEqualTo(26+20+12+2);
+ }
private void recordSamePinsManyShot(int shotCount, int pins) {
for (int count = 0; count < shotCount; count++) {
game.recordOneShot(pins);
}
}
}
Green
public class BowlingGame {
private int totalScore = 0;
private boolean isSpare = false;
private int beforePins = 0;
private int shotCount = 1;
private int strikeAddScoreCount = 0;
private int doubleAddScoreCount = 0;
public void recordOneShot(int pins) {
totalScore += pins;
calcSpareAddScore(pins);
calcStrikeAddScore(pins);
beforePins = pins;
- shotCount = shotCount == 1 && strikeAddScoreCount < 2 ? 2 : 1;
+ shotCount = shotCount == 1 && strikeAddScoreCount < 2 && doubleAddScoreCount < 2 ? 2 : 1;
}
public int getTotalScore() {
return totalScore;
}
private void calcSpareAddScore(int pins) {
if (isSpare) {
totalScore += pins;
isSpare = false;
}
if (shotCount == 2 && pins + beforePins == 10) {
isSpare = true;
}
}
private void calcStrikeAddScore(int pins) {
if (strikeAddScoreCount > 0) {
totalScore += pins;
strikeAddScoreCount -= 1;
}
if (doubleAddScoreCount > 0) {
totalScore += pins;
doubleAddScoreCount -= 1;
}
if (pins == 10) {
if (strikeAddScoreCount == 0) {
strikeAddScoreCount = 2;
} else {
doubleAddScoreCount = 2;
}
}
}
}
public class BowlingGame {
private int totalScore = 0;
private boolean isSpare = false;
private int beforePins = 0;
private int shotCount = 1;
private int strikeAddScoreCount = 0;
private int doubleAddScoreCount = 0;
public void recordOneShot(int pins) {
totalScore += pins;
calcSpareAddScore(pins);
calcStrikeAddScore(pins);
beforePins = pins;
shotCount = shotCount == 1 && strikeAddScoreCount < 2 && doubleAddScoreCount < 2 ? 2 : 1;
}
public int getTotalScore() {
return totalScore;
}
private void calcSpareAddScore(int pins) {
if (isSpare) {
totalScore += pins;
isSpare = false;
}
checkSpare(pins);
}
private void checkSpare(int pins) {
if (shotCount == 2 && pins + beforePins == 10) {
isSpare = true;
}
}
private void calcStrikeAddScore(int pins) {
- if (strikeAddScoreCount > 0) {
- totalScore += pins;
- strikeAddScoreCount -= 1;
- }
- if (doubleAddScoreCount > 0) {
- totalScore += pins;
- doubleAddScoreCount -= 1;
- }
- if (pins == 10) {
- if (strikeAddScoreCount == 0) {
- strikeAddScoreCount = 2;
- } else {
- doubleAddScoreCount = 2;
- }
- }
+ addStrikeScore(pins);
+ addDoubleScore(pins);
+ if (isStrike(pins)) {
+ recognizeStrikeAddCount();
+ }
}
+ private void addStrikeScore(int pins) {
+ if (strikeAddScoreCount > 0) {
+ totalScore += pins;
+ strikeAddScoreCount -= 1;
+ }
+ }
+
+ private void addDoubleScore(int pins) {
+ if (doubleAddScoreCount > 0) {
+ totalScore += pins;
+ doubleAddScoreCount -= 1;
+ }
+ }
+
+ private boolean isStrike(int pins) {
+ return pins == 10;
+ }
+
+ private void recognizeStrikeAddCount() {
+ if (strikeAddScoreCount == 0) {
+ strikeAddScoreCount = 2;
+ } else {
+ doubleAddScoreCount = 2;
+ }
+ }
}
Red
import static org.assertj.core.api.Assertions.assertThat;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
public class BowlingGameTest {
private BowlingGame game;
@BeforeEach
public void setup() {
game = new BowlingGame();
}
// ry
+ @Test
+ public void test_one_frame_score_when_all_garter() {
+ recordSamePinsManyShot(20, 0);
+ assertThat(game.getFrameScore(1)).isEqualTo(0);
+ }
private void recordSamePinsManyShot(int shotCount, int pins) {
for (int count = 0; count < shotCount; count++) {
game.recordOneShot(pins);
}
}
}
Green
public BowlingGame {
// ry
+ public int getFrameScore(int frameNum) {
+ return 0;
+ }
}
――Wenn Sie versuchen, einen Testfall hinzuzufügen, der berechnet werden muss ... Wird er bisher wiederholt?
Rahmenklasse eingeführt
public class Frame {
public void recordOneShot(int pins) {
}
public int getScore(int frameNum) {
return 0;
}
}
Red
import static org.assertj.core.api.Assertions.assertThat;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
class FrameTest {
private Frame frame;
@BeforeEach
public void setup() {
frame = new Frame();
}
@Test
public void test_one_frame_score_when_all_one_pin() {
frame.recordOneShot(1);
assertThat(frame.getScore(1)).isEqualTo(1);
}
}
Green
public class Frame {
private int score = 0;
public void recordOneShot(int pins) {
+ score += pins;
}
public int getScore(int frameNum) {
- return 0;
+ return score;
}
}
public class BowlingGame {
private int totalScore = 0;
private boolean isSpare = false;
private int beforePins = 0;
private int shotCount = 1;
private int strikeAddScoreCount = 0;
private int doubleAddScoreCount = 0;
+ private Frame frame = new Frame();
// ry
+ public int getFrameScore(int frameNum) {
+ return frame.getScore(frameNum);
+ }
// ry
}
import static org.assertj.core.api.Assertions.assertThat;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
public class BowlingGameTest {
private BowlingGame game;
@BeforeEach
public void setup() {
game = new BowlingGame();
}
// ry
+ @Test
+ public void test_one_frame_score_when_all_garter() {
+ recordSamePinsManyShot(20, 0);
+ assertThat(game.getFrameScore(1)).isEqualTo(0);
+ }
private void recordSamePinsManyShot(int shotCount, int pins) {
for (int count = 0; count < shotCount; count++) {
game.recordOneShot(pins);
}
}
}
--Statische Entwurfsprüfung: Delegieren Sie Folgendes an die Frame-Klasse
MECE (gegenseitig ausschließend und kollektiv erschöpfend): Eine Vogelperspektive des Klassendesigns aus der Perspektive, dass keine Doppelarbeit und keine Auslassungen vorgenommen werden
Refactor, indem Sie sich nur auf die Funktionen konzentrieren, die im Moment klar sind
Red
import static org.assertj.core.api.Assertions.assertThat;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
class FrameTest {
private Frame frame;
@BeforeEach
public void setup() {
frame = new Frame();
}
// ry
+ @Test
+ public void test_frame_finish_two_shot() {
+ frame.recordOneShot(1);
+ assertThat(frame.isFinished()).isFalse();
+ frame.recordOneShot(1);
+ assertThat(frame.isFinished()).isTrue();
+ }
}
Green
package bowling;
public class Frame {
private int score = 0;
+ private int shotCount = 0;
public void recordOneShot(int pins) {
score += pins;
+ shotCount++;
}
public int getScore(int frameNum) {
return score;
}
+ public boolean isFinished() {
+ return shotCount >= 2;
+ }
}
Red
import static org.assertj.core.api.Assertions.assertThat;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
class FrameTest {
private Frame frame;
@BeforeEach
public void setup() {
frame = new Frame();
}
// ry
+ @Test
+ public void test_frame_finish_strike() {
+ var frame = new Frame();
+ frame.recordOneShot(10);
+ assertThat(frame.isFinished()).isTrue();
+ }
}
Green
public class Frame {
private int score = 0;
private int shotCount = 0;
public void recordOneShot(int pins) {
score += pins;
shotCount++;
}
public int getScore(int frameNum) {
return score;
}
public boolean isFinished() {
- return shotCount >= 2;
+ return shotCount >= 2 || score >= 10;
}
}
Red
import static org.assertj.core.api.Assertions.assertThat;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
public class BowlingGameTest {
private BowlingGame game;
@BeforeEach
public void setup() {
game = new BowlingGame();
}
// ry
+ @Test
+ public void test_one_frame_score_is_2_when_all_one_pin() {
+ recordSamePinsManyShot(20, 1);
+ for (int frameNum = 0; frameNum < 10; frameNum++) {
+ assertThat(game.getFrameScore(frameNum + 1)).isEqualTo(2);
+ }
+ }
private void recordSamePinsManyShot(int shotCount, int pins) {
for (int count = 0; count < shotCount; count++) {
game.recordOneShot(pins);
}
}
}
Green
import java.util.LinkedList;
public class BowlingGame {
private int totalScore = 0;
private boolean isSpare = false;
private int beforePins = 0;
private int shotCount = 1;
private int strikeAddScoreCount = 0;
private int doubleAddScoreCount = 0;
- private Frame frame = new Frame();
+ private final LinkedList<Frame> frames = new LinkedList<>() {
+ {
+ add(new Frame());
+ }
+ };
public void recordOneShot(int pins) {
+ var frame = frames.getLast();
+ frame.recordOneShot(pins);
totalScore += pins;
calcSpareAddScore(pins);
calcStrikeAddScore(pins);
beforePins = pins;
shotCount = shotCount == 1 && strikeAddScoreCount < 2 && doubleAddScoreCount < 2 ? 2 : 1;
+ if (frame.isFinished()) {
+ frames.add(new Frame());
+ }
}
public int getTotalScore() {
return totalScore;
}
+ public int getFrameScore(int frameNum) {
+ return frames.get(frameNum - 1).getScore();
+ }
// ry
}
Red
import static org.assertj.core.api.Assertions.assertThat;
import org.junit.jupiter.api.Test;
public class FrameTest {
private Frame frame;
@BeforeEach
public void setup() {
frame = new Frame();
}
// ry
+ @Test
+ public void test_spare_when_defect_10_pins_in_second_shot_of_frame() {
+ frame.recordOneShot(5);
+ assertThat(frame.isSpare()).isFalse();
+ frame.recordOneShot(5);
+ assertThat(frame.isSpare()).isTrue();
+ }
}
Green
public class Frame {
private int score = 0;
private int shotCount = 0;
public void recordOneShot(int pins) {
score += pins;
shotCount++;
}
public int getScore() {
return score;
}
public boolean isFinished() {
return shotCount >= 2 || score >= 10;
}
+ public boolean isSpare() {
+ return score == 10 && shotCount >= 2;
+ }
}
Red
import static org.assertj.core.api.Assertions.assertThat;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
public class FrameTest {
private Frame frame;
@BeforeEach
public void setup() {
frame = new Frame();
}
//ry
+ @Test
+ public void test_strike_when_defect_10_pins_in_first_shot_of_frame() {
+ assertThat(frame.isStrike()).isFalse();
+ frame.recordOneShot(10);
+ assertThat(frame.isStrike()).isTrue();
+ }
}
Green
public class Frame {
private int score = 0;
private int shotCount = 0;
public void recordOneShot(int pins) {
score += pins;
shotCount++;
}
public int getScore() {
return score;
}
public boolean isFinished() {
return shotCount >= 2 || score >= 10;
}
public boolean isSpare() {
return score == 10 && shotCount >= 2;
}
+ public boolean isStrike() {
+ return score == 10 && shotCount == 1;
+ }
}
import java.util.LinkedList;
public class BowlingGame {
private int totalScore = 0;
private boolean isSpare = false;
private int strikeAddScoreCount = 0;
private int doubleAddScoreCount = 0;
private final LinkedList<Frame> frames = new LinkedList<>() {
{
add(new Frame());
}
};
public void recordOneShot(int pins) {
var frame = frames.getLast();
frame.recordOneShot(pins);
totalScore += pins;
calcSpareAddScore(pins);
calcStrikeAddScore(pins);
if (frame.isFinished()) {
frames.add(new Frame());
}
}
public int getTotalScore() {
return totalScore;
}
public int getFrameScore(int frameNum) {
return frames.get(frameNum - 1).getScore();
}
private void calcSpareAddScore(int pins) {
if (isSpare) {
totalScore += pins;
isSpare = false;
}
- checkSpare(pins);
+ if (frames.getLast().isSpare()) {
+ isSpare = true;
+ }
}
- private void checkSpare(int pins) {
- if (shotCount == 2 && pins + beforePins == 10) {
- isSpare = true;
- }
- }
private void calcStrikeAddScore(int pins) {
addStrikeScore(pins);
addDoubleScore(pins);
if (isStrike(pins)) {
recognizeStrikeAddCount();
}
}
private void addStrikeScore(int pins) {
if (strikeAddScoreCount > 0) {
totalScore += pins;
strikeAddScoreCount -= 1;
}
}
private void addDoubleScore(int pins) {
if (doubleAddScoreCount > 0) {
totalScore += pins;
doubleAddScoreCount -= 1;
}
}
private boolean isStrike(int pins) {
return pins == 10;
}
private void recognizeStrikeAddCount() {
if (strikeAddScoreCount == 0) {
strikeAddScoreCount = 2;
} else {
doubleAddScoreCount = 2;
}
}
}
import java.util.LinkedList;
public class BowlingGame {
private int totalScore = 0;
private boolean isSpare = false;
private int strikeAddScoreCount = 0;
private int doubleAddScoreCount = 0;
private final LinkedList<Frame> frames = new LinkedList<>() {
{
add(new Frame());
}
};
public void recordOneShot(int pins) {
var frame = frames.getLast();
frame.recordOneShot(pins);
totalScore += pins;
calcSpareAddScore(pins);
calcStrikeAddScore(pins);
if (frame.isFinished()) {
frames.add(new Frame());
}
}
public int getTotalScore() {
return totalScore;
}
public int getFrameScore(int frameNum) {
return frames.get(frameNum - 1).getScore();
}
private void calcSpareAddScore(int pins) {
if (isSpare) {
totalScore += pins;
isSpare = false;
}
if (frames.getLast().isSpare()) {
isSpare = true;
}
}
private void calcStrikeAddScore(int pins) {
addStrikeScore(pins);
addDoubleScore(pins);
- if (isStrike(pins)) {
+ if (frames.getLast().isStrike()) {
recognizeStrikeAddCount();
}
}
private void addStrikeScore(int pins) {
if (strikeAddScoreCount > 0) {
totalScore += pins;
strikeAddScoreCount -= 1;
}
}
private void addDoubleScore(int pins) {
if (doubleAddScoreCount > 0) {
totalScore += pins;
doubleAddScoreCount -= 1;
}
}
private void recognizeStrikeAddCount() {
if (strikeAddScoreCount == 0) {
strikeAddScoreCount = 2;
} else {
doubleAddScoreCount = 2;
}
}
}
Red
import static org.assertj.core.api.Assertions.assertThat;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
class FrameTest {
private Frame frame;
@BeforeEach
public void setup() {
frame = new Frame();
}
// ry
+ @Test
+ public void test_spare_add_bonus_score() {
+ frame.recordOneShot(5);
+ frame.recordOneShot(5);
+ frame.addBonusScore(5);
+ assertThat(frame.getScore()).isEqualTo(15);
+ }
}
Green
package bowling;
public class Frame {
private int score = 0;
private int shotCount = 0;
public void recordOneShot(int pins) {
score += pins;
shotCount++;
}
public int getScore() {
return score;
}
public boolean isFinished() {
return shotCount >= 2 || score >= 10;
}
public boolean isSpare() {
return score == 10 && shotCount >= 2;
}
public boolean isStrike() {
return score == 10 && shotCount == 1;
}
+ public void addBonusScore(int bonusScore) {
+ score += bonusScore;
+ }
}
Red
import static org.assertj.core.api.Assertions.assertThat;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
class FrameTest {
private Frame frame;
@BeforeEach
public void setup() {
frame = new Frame();
}
// ry
+ @Test
+ public void test_spare_frame_score_add_next_pins() {
+ game.recordOneShot(4);
+ game.recordOneShot(6);
+ game.recordOneShot(5);
+ assertThat(game.getFrameScore(1)).isEqualTo(15);
+ assertThat(game.getTotalScore()).isEqualTo(20);
+ }
}
Green
import java.util.LinkedList;
public class BowlingGame {
private int totalScore = 0;
private boolean isSpare = false;
+ private Frame spareFrame = null;
private int strikeAddScoreCount = 0;
private int doubleAddScoreCount = 0;
private final LinkedList<Frame> frames = new LinkedList<>() {
{
add(new Frame());
}
};
// ry
private void calcSpareAddScore(int pins) {
if (isSpare) {
totalScore += pins;
isSpare = false;
+ spareFrame.addBonusScore(pins);
+ spareFrame = null;
}
if (frames.getLast().isSpare()) {
isSpare = true;
+ spareFrame = frames.getLast();
}
}
// ry
}
Red
import static org.assertj.core.api.Assertions.assertThat;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
class FrameTest {
private Frame frame;
@BeforeEach
public void setup() {
frame = new Frame();
}
// ry
@Test
public void test_strike_frame_score_add_twice_next_pins() {
game.recordOneShot(10);
game.recordOneShot(3);
game.recordOneShot(4);
game.recordOneShot(2);
recordSamePinsManyShot(15, 0);
assertThat(game.getTotalScore()).isEqualTo(26);
assertThat(game.getFrameScore(1)).isEqualTo(17);
}
}
Green
import java.util.LinkedList;
public class BowlingGame {
private int totalScore = 0;
private boolean isSpare = false;
private Frame spareFrame = null;
+ private Frame strikeFrame = null;
private int strikeAddScoreCount = 0;
private int doubleAddScoreCount = 0;
private final LinkedList<Frame> frames = new LinkedList<>() {
{
add(new Frame());
}
};
// ry
private void addStrikeScore(int pins) {
if (strikeAddScoreCount > 0) {
totalScore += pins;
strikeAddScoreCount -= 1;
+ strikeFrame.addBonusScore(pins);
}
}
private void addDoubleScore(int pins) {
if (doubleAddScoreCount > 0) {
totalScore += pins;
doubleAddScoreCount -= 1;
}
}
private void recognizeStrikeAddCount() {
if (strikeAddScoreCount == 0) {
strikeAddScoreCount = 2;
+ strikeFrame = frames.getLast();
} else {
doubleAddScoreCount = 2;
}
}
}
Red
import static org.assertj.core.api.Assertions.assertThat;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
class FrameTest {
private Frame frame;
@BeforeEach
public void setup() {
frame = new Frame();
}
// ry
+ @Test
+ public void test_strike_double_frame_score() {
+ game.recordOneShot(10);
+ game.recordOneShot(10);
+ game.recordOneShot(4);
+ game.recordOneShot(2);
+ recordSamePinsManyShot(14, 0);
+ assertThat(game.getTotalScore()).isEqualTo(46);
+ assertThat(game.getFrameScore(1)).isEqualTo(24);
+ assertThat(game.getFrameScore(2)).isEqualTo(16);
+ }
}
Green
import java.util.LinkedList;
public class BowlingGame {
private int totalScore = 0;
private boolean isSpare = false;
private Frame spareFrame = null;
private Frame strikeFrame = null;
+ private Frame doubleFrame = null;
private int strikeAddScoreCount = 0;
private int doubleAddScoreCount = 0;
private final LinkedList<Frame> frames = new LinkedList<>() {
{
add(new Frame());
}
};
// ry
private void addDoubleScore(int pins) {
if (doubleAddScoreCount > 0) {
totalScore += pins;
doubleAddScoreCount -= 1;
+ doubleFrame.addBonusScore(pins);
}
}
private void recognizeStrikeAddCount() {
if (strikeAddScoreCount == 0) {
strikeAddScoreCount = 2;
strikeFrame = frames.getLast();
} else {
doubleAddScoreCount = 2;
+ doubleFrame = frames.getLast();
}
}
}
Verschieben Sie als Nächstes das Urteil von strikeAddScoreCount und doubleAddScoreCount in Frame.
Sogar bis jetzt scheint es, dass ich es mir bis zu einem gewissen Grad vorstellen kann, bis jetzt einmal (erschöpft)
Ich weiß es nicht für mein Verständnis.
Machen Sie zunächst (Entschuldigung für das grobe Bild) bitte das folgende Bild aus dem Bild.
――Der äußerste Kreis unten ist das gesamte Entwicklungsziel, und es gibt mehrere Probleme / Probleme (graue Kreise im Bild unten) = Das Entwicklungsziel ist eine Sammlung (Klumpen) von Problemen / Problemen
Basierend auf dem oben Gesagten, wenn es darum geht, tatsächlich mit der Entwicklung fortzufahren, wenn das Verständnis des Ziels für diese Masse schlecht ist,
――Ich weiß nicht, womit ich anfangen soll ――Ich weiß nicht, wie ich vorgehen soll
Ich denke, es wird. Auf der anderen Seite TDD Löse in der Reihenfolge von der, die einzeln von außen gelöst werden kann. Auch wenn es auf den ersten Blick ein Umweg war. Im Idealfall kann der kürzeste Weg die Probleme lösen, aber es ist praktisch unmöglich, die Probleme mit dem kürzesten Weg zu lösen, wenn ein innerer Teil noch nicht sichtbar ist. Wenn Sie der Meinung sind, dass dies das kürzeste ist und Sie versuchen, mehrere Probleme gleichzeitig zu lösen, ist dies ziemlich kompliziert und dauert länger. Oft kommt es vor, dass Sie komplizierte Arbeiten ausführen.
Deshalb zerlegen wir es in kleinere Partikel und lösen die Probleme nacheinander.
Indem Sie sich nacheinander entwirren, nähern Sie sich allmählich dem Kern und verbessern Ihr Verständnis des Themas. Wenn Sie den Kern oder ein Problem in der Nähe erreichen, wird sich Ihr Verständnis des Themas vertiefen und Sie können die richtigen Entscheidungen über das Problem treffen (deshalb sollten Sie sich erst entscheiden, wenn Sie die richtige Entscheidung treffen können. Selbst wenn Sie eine vorläufige Entscheidung in einem Zustand treffen, in dem Sie dies noch nicht tun können, handelt es sich im Allgemeinen um einen zusätzlichen Build.
Bei der tatsächlichen Implementierung denke ich, dass es ** definiert / deklariert, welches Problem durch Schreiben eines Testfalls ** gelöst werden soll.
Basierend auf dem oben Gesagten ist TDD unter Berücksichtigung des TDD-Ansatzes
** Setzen Sie sich kleine Ziele (Ziele, die angestrebt werden sollen, und zu lösende Probleme), indem Sie Testfälle schreiben, und konzentrieren Sie sich auf nur ein Ziel vor Ihnen. Dies wird wiederholt. ** **.
** Indem Sie es separat tun, auch statisches Design und dynamisches Design **
--Statisches Design ≒ Berücksichtigen Sie nur die Logik / den Algorithmus (wenn Rot → Grün). --Dynamisches Design ≒ Berücksichtigen Sie nur das Klassen- / Schnittstellendesign (zum Zeitpunkt von Refactor).
Wenn Sie eines ausführen, können Sie sich auf das andere konzentrieren. Durch Drehen des Rot / Grün / Refactor-Zyklus können Sie das Design / die Implementierung verfeinern und dabei die Qualität des Designs in gewissem Maße beibehalten (abhängig von der Kompetenz des Entwicklers). Ich denke.
Da Refactor auf der Sicherheit und Zuverlässigkeit basiert, die mit den folgenden Sicherheiten erzielt werden können, ist es außerdem möglich, sich auf die Arbeit des Denkens über dynamisches Design zu konzentrieren.
Ich habe verstanden. das ist alles
[Buch: Einführung in die testgetriebene TDD-Entwicklung ab sofort](https://www.amazon.co.jp/%E3%81%93%E3%82%8C%E3%81%8B%E3%82%89%E3 % 81% AF% E3% 81% 98% E3% 82% 81% E3% 82% 8BTDD-% E3% 83% 86% E3% 82% B9% E3% 83% 88% E9% A7% 86% E5% 8B% 95% E9% 96% 8B% E7% 99% BA% E5% 85% A5% E9% 96% 80-ThinkIT-Books-% E5% 90% 89% E8% B0% B7-ebook / dp / B00VFQ7WCM / ref = cm_cr_arp_d_product_top? ie = UTF8)
[Buch: Test Driven Development](https://www.amazon.co.jp/%E3%83%86%E3%82%B9%E3%83%88%E9%A7%86%E5%8B%95 % E9% 96% 8B% E7% 99% BA-% EF% BC% AB% EF% BD% 85% EF% BD% 8E% EF% BD% 94% EF% BC% A2% EF% BD% 85% EF% BD% 83% EF% BD% 8B-ebook / dp / B077D2L69C / ref = sr_1_1? __Mk_ja_JP =% E3% 82% AB% E3% 82% BF% E3% 82% AB% E3% 83% 8A & dchild = 1 & Schlüsselwörter =% E3% 83% 86% E3% 82% B9% E3% 83% 88% E9% A7% 86% E5% 8B% 95% E9% 96% 8B% E7% 99% BA & qid = 1605338667 & s = digitaler Text & sr = 1-1)
Recommended Posts