@@ -0,0 +1,196 @@
+package com.codesquad.baseball09.model;
+
+import static com.codesquad.baseball09.model.Status.BALL;
+import static com.codesquad.baseball09.model.Status.HIT;
+import static com.codesquad.baseball09.model.Status.OUT;
+import static com.codesquad.baseball09.model.Status.STRIKE;
+
+import com.fasterxml.jackson.annotation.JsonIgnore;
+
+public class InningStatus {
+
+  @JsonIgnore
+  private Long id;
+  private Long gameId;
+  private int inning;
+  private int strike;
+  private int ball;
+  private int out;
+  private int hit;
+
+  public InningStatus(Long id, Long gameId, int inning, int strike, int ball, int out, int hit) {
+    this.id = id;
+    this.gameId = gameId;
+    this.inning = inning;
+    this.strike = strike;
+    this.ball = ball;
+    this.out = out;
+    this.hit = hit;
+  }
+
+  private InningStatus(Long gameId, int inning, int strike, int ball, int out, int hit) {
+    this.gameId = gameId;
+    this.inning = inning;
+    this.strike = strike;
+    this.ball = ball;
+    this.out = out;
+    this.hit = hit;
+  }
+
+  public InningStatus(int strike, int ball, int out, int hit) {
+    this.strike = strike;
+    this.ball = ball;
+    this.out = out;
+    this.hit = hit;
+  }
+
+  public static InningStatus of(Long gameId, int inning, int strike, int ball, int out, int hit) {
+    return new InningStatus(gameId, inning, strike, ball, out, hit);
+  }
+
+  public int plus(Status status) {
+    int value = 0;
+
+    if (STRIKE.equals(status)) {
+      strike++;
+      value = checkThreeStrike();
+    } else if (BALL.equals(status)) {
+      ball++;
+      value = checkFourBall();
+    } else if (OUT.equals(status)) {
+      out++;
+      resetStrikeAndBall();
+      value = checkThreeOut();
+    } else if (HIT.equals(status)) {
+      hit++;
+      resetStrikeAndBall();
+      value = checkFourHit();
+    }
+    return value;
+  }
+
+  private void resetStrikeAndBall() {
+    this.strike = 0;
+    this.ball = 0;
+  }
+
+  private void resetAll() {
+    resetStrikeAndBall();
+    this.out = 0;
+    this.hit = 0;
+  }
+
+  private int checkFourHit() {
+    if (this.hit == 4) {
+      resetStrikeAndBall();
+      this.hit--;
+      return 1;
+    }
+    return 0;
+  }
+
+  private int checkThreeOut() {
+    if (this.out == 3) {
+      resetAll();
+      return -1;
+    }
+    return 0;
+  }
+
+  private int checkFourBall() {
+    if (this.ball == 4) {
+      resetStrikeAndBall();
+      plus(HIT);
+    }
+    return 2;
+  }
+
+  private int checkThreeStrike() {
+    if (this.strike == 3) {
+      resetStrikeAndBall();
+      plus(OUT);
+    }
+    return 2;
+  }
+
+  public Long getId() {
+    return id;
+  }
+
+  public Long getGameId() {
+    return gameId;
+  }
+
+  public int getInning() {
+    return inning;
+  }
+
+  public int getStrike() {
+    return strike;
+  }
+
+  public int getBall() {
+    return ball;
+  }
+
+  public int getOut() {
+    return out;
+  }
+
+  public int getHit() {
+    return hit;
+  }
+
+  public static final class Builder {
+
+    private Long id;
+    private Long gameId;
+    private int inning;
+    private int strike;
+    private int ball;
+    private int out;
+    private int hit;
+
+    public Builder() {
+    }
+
+    public Builder id(Long id) {
+      this.id = id;
+      return this;
+    }
+
+    public Builder gameId(Long gameId) {
+      this.gameId = gameId;
+      return this;
+    }
+
+    public Builder inning(int inning) {
+      this.inning = inning;
+      return this;
+    }
+
+    public Builder strike(int strike) {
+      this.strike = strike;
+      return this;
+    }
+
+    public Builder ball(int ball) {
+      this.ball = ball;
+      return this;
+    }
+
+    public Builder out(int out) {
+      this.out = out;
+      return this;
+    }
+
+    public Builder hit(int hit) {
+      this.hit = hit;
+      return this;
+    }
+
+    public InningStatus build() {
+      return new InningStatus(id, gameId, inning, strike, ball, out, hit);
+    }
+  }
+}

리뷰: 네 개의 행위에 대해 결과를 반영해야 하다 보니, 네 개의 `case` 를 갖는 `switch` 문과 같은 구현이 나오게 되었습니다.
이를 어떻게 객체지향적으로, 깔끔하게 풀 수 있을까요. 

단순히 생각해보기로는 `InningCount` 라는 객체가 `BallCount` 객체를 다시 갖고 있으면서, 아웃 카운트와 볼 카운트를 관리하는 방식이 떠오릅니다. 
각 행위에 해당하는 `enum` 을 객체에 넘기면 그 객체가 나머지 일을 처리하게 되는 거죠. 

한 번 생각해보시고 대댓글로 계속 구현에 대해 의견 나눠보면 재밌겠네요.