ewhk9887/korean_code_reviews_from_github huggingface dataset:
@@ -2,22 +2,28 @@
 
 public class Car{
 
-    private String name;
-    private int position = 0;
+    long number;
+    int length;
+    State state;
 
-    public Car(String name){
-        this.name = name;
+    public Car(long number) {
+        this.number = number;
+        length = 0;
     }
 
-    public String getName() {
-        return name;
+    public int moveCount() {
+        return length;
     }
 
-    public int getPosition(){
-        return position;
+    public long getCarNum() {
+        return number;
     }
 
-    public void move(){
-        position++;
+    public void changeState(State cmd) {
+        state = cmd;
+    }
+
+    public void move() {
+        length = state.execute(length);
     }
 }
\ No newline at end of file

리뷰: cmd 의 의미가 무엇일까요? command? 스터디 규칙은 축약형 단어를 사용하지 말자~ 입니다
@@ -2,22 +2,28 @@
 
 public class Car{
 
-    private String name;
-    private int position = 0;
+    long number;
+    int length;
+    State state;
 
-    public Car(String name){
-        this.name = name;
+    public Car(long number) {
+        this.number = number;
+        length = 0;
     }
 
-    public String getName() {
-        return name;
+    public int moveCount() {
+        return length;
     }
 
-    public int getPosition(){
-        return position;
+    public long getCarNum() {
+        return number;
     }
 
-    public void move(){
-        position++;
+    public void changeState(State cmd) {
+        state = cmd;
+    }
+
+    public void move() {
+        length = state.execute(length);
     }
 }
\ No newline at end of file

리뷰: state 의 기본값이 세팅되어있지 않은데, 이 클래스가 state 패턴을 적용한 것인지 모르는 사람은 car.move() 를 사용했을 경우에 NPE 가 발생하지 않을까요~?
@@ -0,0 +1,38 @@
+package controller;
+
+import function.RandomNumberMaker;
+import model.Car;
+import model.State;
+import model.Movable;
+import model.UnMovable;
+
+import java.util.List;
+
+public class CarController {
+
+    private static final int MOVE_CONDITION = 4;
+
+    public void registerCars(List<Car> cars, long len) {
+        for (int i = 0; i < len; i++) {
+            cars.add(new Car(i));
+        }
+    }
+
+    public void moveCar(List<Car> cars) {
+        for (Car car : cars) {
+            car.changeState(checkMoveOrStop(car));
+            car.move();
+        }
+    }
+
+    private State checkMoveOrStop(Car car) {
+        if (getRandomNumber() >= MOVE_CONDITION) {
+            return new Movable();
+        }
+        return new UnMovable();
+    }
+
+    private int getRandomNumber() {
+        return RandomNumberMaker.getRandomNumber();
+    }
+}

리뷰: 상태 패턴을 활용하신게 신선하네요~ 

다만 전진과 정지 뿐이고 상태의 전이가 없을 뿐더러 조건문이 복잡하지 않은 상태에서 적용하기엔 과하지 않나라는 고민도 해보시면 좋을 것 같아요.

move(int condition) 메서드에서 분기쳐서 전진, 정지를 수행하는 것과,

움직임 관련 상태를 정의하고, CarController 에서 분기쳐서 condition 체크하고 움직임 관련 상태를 바꿔주도록 구현한 다음, Car.move 에서 또 분기를 통해 상태값을 체크해서 행위를 결정하는 것(을 개선한 것이 상태 패턴 적용버전인데)

무엇이 더 복잡하고 심플한지 고민해보셔도 좋을 것 같아요. 간단하게 행위로 풀 것을 상태로 만들어서 패턴의 적용이 코드의 목적이 된건 아닌지도 고민해보시면 좋을 것 같습니다 ~ 

학습 목적으로는 좋은 시도인 것 같아요~
@@ -1,16 +1,54 @@
 package view;
 
+import java.io.InputStream;
+import java.util.InputMismatchException;
 import java.util.Scanner;
 
-public class InputView{
+public class InputView {
 
-    public static String[] inputCarName(Scanner scanner){
-        System.out.println("경주할 차의 이름을 입력하세요. (이름은 쉼표(,) 기준으로 구분)");
-        return scanner.nextLine().split(",");
+    Scanner sc;
+    private static final String CARS_COUNT = "자동차 대수는 몇 대 인가요?";
+    private static final String PUT_NATURAL_NUMBER = "음수가 아닌 자연수를 입력해주세요";
+    private static final String TRIAL_COUNT = "시도할 횟수는 몇 회 인가요?";
+    private static final String DO_NOT_PUT_STRING = "문자열이 아닌 자연수를 입력해주세요";
+
+    public InputView() {
+        sc = new Scanner(System.in);
+    }
+
+    public long inputTotalCarNum() {
+        System.out.println(CARS_COUNT);
+        long carCount = 0L;
+        try {
+            carCount = Long.parseLong(sc.nextLine());
+            if (carCount <= 0) {
+                throw new IllegalArgumentException();
+            }
+        } catch (IllegalArgumentException exception) {
+            System.out.println(PUT_NATURAL_NUMBER);
+            return inputTotalCarNum();
+        } catch (InputMismatchException exception) {
+            System.out.println(DO_NOT_PUT_STRING);
+            return inputTotalCarNum();
+        }
+        return carCount;
     }
 
-    public static int inputNumberOfTrials(Scanner scanner){
-        System.out.println("시도할 횟수는 몇회인가요?");
-        return scanner.nextInt();
+    public int inputTotalTrial() {
+        System.out.println(TRIAL_COUNT);
+        int trial = 0;
+        try {
+            trial = Integer.parseInt(sc.nextLine());
+            if (trial <= 0) {
+                throw new IllegalArgumentException();
+            }
+        } catch (IllegalArgumentException exception) {
+            System.out.println(PUT_NATURAL_NUMBER);
+            return inputTotalTrial();
+        } catch (InputMismatchException exception) {
+            System.out.println(DO_NOT_PUT_STRING);
+            return inputTotalTrial();
+        }
+        return trial;
     }
-}
\ No newline at end of file
+}

리뷰: 코드의 포맷팅도 컨벤션의 일종입니다.
intellij 의 코드 포맷팅 단축키를 활용해서 정렬해보시면 어떨까요?
@@ -1,39 +1,53 @@
 package model;
 
-import static org.junit.Assert.*;
+import org.junit.jupiter.api.DisplayName;
+import org.junit.jupiter.api.Test;
 
-import org.junit.Before;
-import org.junit.Test;
+import static org.assertj.core.api.Assertions.*;
 
-public class CarTest {
+class CarTest {
 
-    private Car tesla;
-    private Car kia;
-    private Car hyundai;
-
-    @Before
-    public void setup(){
-        tesla = new Car("tesla");
-        kia = new Car("kia");
-        hyundai = new Car("hyundai");
+    @Test
+    @DisplayName("차 번호가 식별자이다")
+    public void identification() throws Exception{
+        //given
+        Car car1 = new Car(1L);
+        Car car2 = new Car(2L);
+
+        //when
+        long carNum1 = car1.getCarNum();
+        long carNum2 = car2.getCarNum();
+
+        //then
+        assertThat(carNum1).isEqualTo(1L);
+        assertThat(carNum2).isEqualTo(2L);
     }
 
     @Test
-    public void getNameTest() {
-        assertEquals("tesla", tesla.getName());
-        assertEquals("kia", kia.getName());
-        assertEquals("hyundai", hyundai.getName());
+    @DisplayName("moveable 상태면 한 칸 전진")
+    public void go() throws Exception{
+        //given
+        Car car1 = new Car(1L);
+        car1.changeState(new Movable());
+
+        //when
+        car1.move();
+
+        //then
+        assertThat(car1.moveCount()).isEqualTo(1);
     }
 
     @Test
-    public void getPositionAndMoveTest(){
-        tesla.move(); tesla.move(); tesla.move();
-        assertEquals(3, tesla.getPosition());
+    @DisplayName("unmovable 상태면 전진하지 않음")
+    public void stop() throws Exception{
+        //given
+        Car car1 = new Car(1L);
+        car1.changeState(new UnMovable());
 
-        kia.move(); kia.move();
-        assertEquals(2, kia.getPosition());
+        //when
+        car1.move();
 
-        hyundai.move();
-        assertEquals(1, hyundai.getPosition());
+        //then
+        assertThat(car1.moveCount()).isEqualTo(0);
     }
-}
\ No newline at end of file
+}

리뷰: junit5 부터는 접근제어자를 생략가능해서 좀 더 가독성 있고 간결한 테스트 코드를 작성할 수 있습니다~
@@ -1,39 +1,53 @@
 package model;
 
-import static org.junit.Assert.*;
+import org.junit.jupiter.api.DisplayName;
+import org.junit.jupiter.api.Test;
 
-import org.junit.Before;
-import org.junit.Test;
+import static org.assertj.core.api.Assertions.*;
 
-public class CarTest {
+class CarTest {
 
-    private Car tesla;
-    private Car kia;
-    private Car hyundai;
-
-    @Before
-    public void setup(){
-        tesla = new Car("tesla");
-        kia = new Car("kia");
-        hyundai = new Car("hyundai");
+    @Test
+    @DisplayName("차 번호가 식별자이다")
+    public void identification() throws Exception{
+        //given
+        Car car1 = new Car(1L);
+        Car car2 = new Car(2L);
+
+        //when
+        long carNum1 = car1.getCarNum();
+        long carNum2 = car2.getCarNum();
+
+        //then
+        assertThat(carNum1).isEqualTo(1L);
+        assertThat(carNum2).isEqualTo(2L);
     }
 
     @Test
-    public void getNameTest() {
-        assertEquals("tesla", tesla.getName());
-        assertEquals("kia", kia.getName());
-        assertEquals("hyundai", hyundai.getName());
+    @DisplayName("moveable 상태면 한 칸 전진")
+    public void go() throws Exception{
+        //given
+        Car car1 = new Car(1L);
+        car1.changeState(new Movable());
+
+        //when
+        car1.move();
+
+        //then
+        assertThat(car1.moveCount()).isEqualTo(1);
     }
 
     @Test
-    public void getPositionAndMoveTest(){
-        tesla.move(); tesla.move(); tesla.move();
-        assertEquals(3, tesla.getPosition());
+    @DisplayName("unmovable 상태면 전진하지 않음")
+    public void stop() throws Exception{
+        //given
+        Car car1 = new Car(1L);
+        car1.changeState(new UnMovable());
 
-        kia.move(); kia.move();
-        assertEquals(2, kia.getPosition());
+        //when
+        car1.move();
 
-        hyundai.move();
-        assertEquals(1, hyundai.getPosition());
+        //then
+        assertThat(car1.moveCount()).isEqualTo(0);
     }
-}
\ No newline at end of file
+}

리뷰: 이거는 getter 를 테스트하는 격이라서 테스트가 필요가 없을 것 같다는 생각이 듭니다.
~할 때 ~ 한다. 라고 테스트명을 작성해주시면 나중에 클래스의 기능 명세로도 활용되어 좋은 테스트가 될 것 같아요
@@ -0,0 +1,38 @@
+package controller;
+
+import function.RandomNumberMaker;
+import model.Car;
+import model.State;
+import model.Movable;
+import model.UnMovable;
+
+import java.util.List;
+
+public class CarController {
+
+    private static final int MOVE_CONDITION = 4;
+
+    public void registerCars(List<Car> cars, long len) {
+        for (int i = 0; i < len; i++) {
+            cars.add(new Car(i));
+        }
+    }
+
+    public void moveCar(List<Car> cars) {
+        for (Car car : cars) {
+            car.changeState(checkMoveOrStop(car));
+            car.move();
+        }
+    }
+
+    private State checkMoveOrStop(Car car) {
+        if (getRandomNumber() >= MOVE_CONDITION) {
+            return new Movable();
+        }
+        return new UnMovable();
+    }
+
+    private int getRandomNumber() {
+        return RandomNumberMaker.getRandomNumber();
+    }
+}

리뷰: 처음에는 분기 처리하여 움직임을 바꿔줬습니다. 
하지만 예제 코드로만 state 패턴을 학습해서, 이번 기회에 애플리케이션에 사용해보고 싶었습니다.

말씀대로 과하다고 생각합니다. 처음이라서 더 잘해봐야지라는 생각으로 그랬던 것 같아요,, !
또한, 제가 어느정도 공부를 했는지 모르시니까 여기까지 공부해봤어요라고 표현하고 싶었습니다.
@@ -0,0 +1,80 @@
+package controller;
+
+import domain.blackjack.BlackjackGame;
+import domain.card.Deck;
+import domain.user.*;
+import view.InputView;
+import view.ResultView;
+
+import java.math.BigDecimal;
+import java.util.ArrayList;
+import java.util.List;
+
+import static java.util.stream.Collectors.toList;
+
+public class BlackjackController {
+
+    public void run() {
+        Users users = inputUsers();
+        BlackjackGame blackjackGame = new BlackjackGame(users, new Deck());
+        runDealPhase(blackjackGame);
+        runPlayersPhase(blackjackGame);
+        runDealerPhase(blackjackGame);
+        ResultView.printResult(blackjackGame);
+    }
+
+    private void runDealPhase(BlackjackGame blackjackGame) {
+        blackjackGame.proceedDealPhase();
+        ResultView.printDealPhaseInformation(blackjackGame);
+    }
+
+    private void runPlayersPhase(BlackjackGame blackjackGame) {
+        while (blackjackGame.isPlayersPhase()) {
+            Player playerOfCurrentTurn = blackjackGame.getPlayerOfCurrentTurn();
+            runPlayerPhase(blackjackGame, playerOfCurrentTurn);
+        }
+    }
+
+    private void runPlayerPhase(BlackjackGame blackjackGame, Player player) {
+        while (player.isWait()) {
+            runChoiceAnswerPhase(blackjackGame, player);
+        }
+    }
+
+    private void runChoiceAnswerPhase(BlackjackGame blackjackGame, Player player) {
+        if (InputView.inputAnswer(player)) {
+            blackjackGame.proceedPlayerHitPhase();
+            ResultView.printPlayerInformation(player);
+            return;
+        }
+        player.stay();
+    }
+
+    private void runDealerPhase(BlackjackGame blackjackGame) {
+        while (blackjackGame.isDealerPhase()) {
+            blackjackGame.proceedDealerHitPhase();
+            ResultView.printDealerHasHit();
+        }
+    }
+
+    private Users inputUsers() {
+        List<Name> names = inputNames();
+        List<User> users = new ArrayList<>();
+        users.add(new Dealer());
+        names.stream()
+                .map(name -> new Player(name, inputBettingMoney(name)))
+                .forEach(users::add);
+        return new Users(users);
+    }
+
+    private List<Name> inputNames() {
+        return InputView.inputNames().stream()
+                .map(Name::new)
+                .collect(toList());
+    }
+
+    private BettingMoney inputBettingMoney(Name name) {
+        BigDecimal amount = InputView.inputBettingMoneyAmount(name);
+        return new BettingMoney(amount);
+    }
+}

리뷰: 메서드가 호출되는 순서를 고려했을 때, `inputUsers` 메서드가 runDealPhase 메서드보다 위에 위치하는게 좋을 것 같아요🤔
@@ -0,0 +1,80 @@
+package controller;
+
+import domain.blackjack.BlackjackGame;
+import domain.card.Deck;
+import domain.user.*;
+import view.InputView;
+import view.ResultView;
+
+import java.math.BigDecimal;
+import java.util.ArrayList;
+import java.util.List;
+
+import static java.util.stream.Collectors.toList;
+
+public class BlackjackController {
+
+    public void run() {
+        Users users = inputUsers();
+        BlackjackGame blackjackGame = new BlackjackGame(users, new Deck());
+        runDealPhase(blackjackGame);
+        runPlayersPhase(blackjackGame);
+        runDealerPhase(blackjackGame);
+        ResultView.printResult(blackjackGame);
+    }
+
+    private void runDealPhase(BlackjackGame blackjackGame) {
+        blackjackGame.proceedDealPhase();
+        ResultView.printDealPhaseInformation(blackjackGame);
+    }
+
+    private void runPlayersPhase(BlackjackGame blackjackGame) {
+        while (blackjackGame.isPlayersPhase()) {
+            Player playerOfCurrentTurn = blackjackGame.getPlayerOfCurrentTurn();
+            runPlayerPhase(blackjackGame, playerOfCurrentTurn);
+        }
+    }
+
+    private void runPlayerPhase(BlackjackGame blackjackGame, Player player) {
+        while (player.isWait()) {
+            runChoiceAnswerPhase(blackjackGame, player);
+        }
+    }
+
+    private void runChoiceAnswerPhase(BlackjackGame blackjackGame, Player player) {
+        if (InputView.inputAnswer(player)) {
+            blackjackGame.proceedPlayerHitPhase();
+            ResultView.printPlayerInformation(player);
+            return;
+        }
+        player.stay();
+    }
+
+    private void runDealerPhase(BlackjackGame blackjackGame) {
+        while (blackjackGame.isDealerPhase()) {
+            blackjackGame.proceedDealerHitPhase();
+            ResultView.printDealerHasHit();
+        }
+    }
+
+    private Users inputUsers() {
+        List<Name> names = inputNames();
+        List<User> users = new ArrayList<>();
+        users.add(new Dealer());
+        names.stream()
+                .map(name -> new Player(name, inputBettingMoney(name)))
+                .forEach(users::add);
+        return new Users(users);
+    }
+
+    private List<Name> inputNames() {
+        return InputView.inputNames().stream()
+                .map(Name::new)
+                .collect(toList());
+    }
+
+    private BettingMoney inputBettingMoney(Name name) {
+        BigDecimal amount = InputView.inputBettingMoneyAmount(name);
+        return new BettingMoney(amount);
+    }
+}

리뷰: 이 부분은 조금 헷갈려서 그런데 베팅을 한다는 의미로 받아들이면 될까요? (바로 아래 `runDealerPhase` 메서드가 있어서 의미가 한 번에 안와닿네요 🙄) 
`딜을 한다` 와 같은 의미로 쓰신걸까요?
@@ -0,0 +1,64 @@
+package domain.user.state;
+
+import domain.card.Card;
+import domain.card.Type;
+import domain.result.GameResult;
+import domain.user.Score;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+public abstract class State {
+    protected static final int BLACKJACK_SCORE = 21;
+    private static final int ACE_IS_ELEVEN = 10;
+    private static final int INITIAL_CARDS_SIZE = 2;
+
+    protected List<Card> cards;
+
+    public State(List<Card> cards) {
+        this.cards = new ArrayList<>(cards);
+    }
+
+    public abstract GameResult findResult(State state);
+
+    protected abstract boolean isBlackjack();
+
+    protected abstract boolean isBust();
+
+    protected abstract boolean isStay();
+
+    public abstract State toStay();
+
+    public void add(Card card) {
+        cards.add(card);
+    }
+
+    public Score calculateScore() {
+        int sum = cards.stream()
+                .map(Card::getType)
+                .mapToInt(Type::getScore)
+                .sum();
+        if (sum + ACE_IS_ELEVEN <= BLACKJACK_SCORE && hasAceCard()) {
+            sum = sum + ACE_IS_ELEVEN;
+        }
+        return new Score(sum);
+    }
+
+    private boolean hasAceCard() {
+        return cards.stream()
+                .anyMatch(Card::isAce);
+    }
+
+    public boolean isInitialCards() {
+        return cards.size() == INITIAL_CARDS_SIZE;
+    }
+
+    public abstract State findNextState();
+
+    public abstract boolean isEnded();
+
+    public List<Card> getCards() {
+        return Collections.unmodifiableList(cards);
+    }
+}

리뷰: ```suggestion
        if (hasAceCard() && sum + ACE_IS_ELEVEN <= BLACKJACK_SCORE) {
```
위와 같이 두 논리식의 순서를 변경하는 것이 더 좋을 것 같아요! 🤔 
왜 그런지 고민해보면 좋을 것 같아요 🤗 
혹시라도 이미 이유를 알고 계신다면 코멘트로 간단하게 남겨주시면 좋을 것 같습니다.
@@ -0,0 +1,64 @@
+package domain.user.state;
+
+import domain.card.Card;
+import domain.card.Type;
+import domain.result.GameResult;
+import domain.user.Score;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+public abstract class State {
+    protected static final int BLACKJACK_SCORE = 21;
+    private static final int ACE_IS_ELEVEN = 10;
+    private static final int INITIAL_CARDS_SIZE = 2;
+
+    protected List<Card> cards;
+
+    public State(List<Card> cards) {
+        this.cards = new ArrayList<>(cards);
+    }
+
+    public abstract GameResult findResult(State state);
+
+    protected abstract boolean isBlackjack();
+
+    protected abstract boolean isBust();
+
+    protected abstract boolean isStay();
+
+    public abstract State toStay();
+
+    public void add(Card card) {
+        cards.add(card);
+    }
+
+    public Score calculateScore() {
+        int sum = cards.stream()
+                .map(Card::getType)
+                .mapToInt(Type::getScore)
+                .sum();
+        if (sum + ACE_IS_ELEVEN <= BLACKJACK_SCORE && hasAceCard()) {
+            sum = sum + ACE_IS_ELEVEN;
+        }
+        return new Score(sum);
+    }
+
+    private boolean hasAceCard() {
+        return cards.stream()
+                .anyMatch(Card::isAce);
+    }
+
+    public boolean isInitialCards() {
+        return cards.size() == INITIAL_CARDS_SIZE;
+    }
+
+    public abstract State findNextState();
+
+    public abstract boolean isEnded();
+
+    public List<Card> getCards() {
+        return Collections.unmodifiableList(cards);
+    }
+}

리뷰: cards 필드를 protected로 둔 이유가 있을까요? 아마도 자식 객체가 부모 객체의 필드에 바로 접근할 수 있게 하기 위해서라고 생각합니다. (ex. Wait 객체) 하지만 잘 생각해보면 하위 객체가 부모 객체의 필드에 직접 접근한다는 것은 캡슐화가 깨졌다는 의미가 됩니다.
즉, 하위 객체는 상위 객체의 내부 상태를 알고 있다는 것입니다.
여기서 상속의 문제점이 드러나는데요. 상속을 사용하게 되면 캡슐화가 깨지는 문제가 발생합니다.
(캡슐화가 깨졌을 때의 문제점이 뭐라고 생각하시나요? 재홍님의 생각을 남겨주시면 좋을 것 같아요!)

저는 하위 객체가 상위 객체의 필드를 필요로한다면 필드를 private로 두고, `getter`를 통해서 접근하도록 제한하여 가급적이면 부모의 필드에 자식이 직접적으로 접근하는 것이 이 문제점을 조금이나마 해결할 수 있다고 생각합니다.

[상속보다 Composition](https://www.youtube.com/watch?v=clbpnp2xYOQ) 영상을 참고해보시면 좋을 것 같습니다.
@@ -0,0 +1,40 @@
+package domain.user.state;
+
+import domain.card.Card;
+import domain.result.GameResult;
+
+import java.util.List;
+
+public class Stay extends Ended {
+
+    public Stay(List<Card> cards) {
+        super(cards);
+    }
+
+    @Override
+    public GameResult findResult(State state) {
+        if (state.isBust()) {
+            return GameResult.WIN;
+        }
+        if (state.isBlackjack()) {
+            return GameResult.LOSE;
+        }
+        return GameResult.from(this.calculateScore().compareTo(state.calculateScore()));
+    }
+
+    @Override
+    protected boolean isBlackjack() {
+        return false;
+    }
+
+    @Override
+    protected boolean isBust() {
+        return false;
+    }
+
+    @Override
+    protected boolean isStay() {
+        return true;
+    }
+
+}

리뷰: Dealer와 Player의 두 State를 `from` 메서드의 파라미터로 넘겨서 GameResult가 스스로 GameResult를 판단하도록하는 것은 어떨까요? 🤔
개인적인 생각으로는 GameResult의 필드(= value)의 값이 불필요하고 일관성이 없는 값(ex. BlackJack의 경우 2)이라고 생각됩니다.
@@ -0,0 +1,50 @@
+package view;
+
+import domain.user.Name;
+import domain.user.Player;
+
+import java.math.BigDecimal;
+import java.util.Arrays;
+import java.util.List;
+import java.util.Scanner;
+
+import static java.util.stream.Collectors.toList;
+
+public class InputView {
+    private static Scanner scanner = new Scanner(System.in);
+    private static final String SEPARATOR = ",";
+    private static final String YES = "y";
+    private static final String NO = "n";
+
+    private InputView() {
+    }
+
+    public static List<String> inputNames() {
+        System.out.println("게임에 참여할 사람의 이름을 입력하세요(쉼표 기준으로 분리).");
+        return Arrays.stream(scanner.nextLine().split(SEPARATOR))
+                .map(String::trim)
+                .collect(toList());
+    }
+
+    public static BigDecimal inputBettingMoneyAmount(Name name) {
+        StringBuilder messageBuilder = new StringBuilder(name.getName());
+        messageBuilder.append("의 배팅 금액은?");
+        System.out.println(messageBuilder);
+        return BigDecimal.valueOf(scanner.nextInt());
+    }
+
+    public static boolean inputAnswer(Player player) {
+        StringBuilder questionBuilder = new StringBuilder(player.getName().getName());
+        questionBuilder.append("는 한장의 카드를 더 받겠습니까? (예는 y, 아니오는 n)");
+        System.out.println(questionBuilder);
+        String answer = scanner.next();
+        validateAnswer(answer);
+        return YES.equals(answer);
+    }
+
+    private static void validateAnswer(String answer) {
+        if (!YES.equals(answer) && !NO.equals(answer)) {
+            throw new IllegalArgumentException("y 또는 n만 입력할 수 있습니다.");
+        }
+    }
+}

리뷰: ```suggestion
        System.out.println(name.getName() + "의 배팅 금액은?");
```
지금 같은 경우에는 위와 같이 변경하는 것이 더 좋지않을까요? 🤔
문자열을 빈번하게 더하는 경우에는 StringBuilder 혹은 StringBuffer를 사용할 수도 있겠지만 지금의 경우에는 문자열을 한 번 더하는 것이 끝이기 때문에 굳이 StringBuilder 객체를 생성할 필요가 없다고 생각됩니다. 

아래의 `inputAnswer` 메서드 또한 동일합니다. 
ResultView 클래스에서도 동일한 고민을 해보셨으면 합니다. 😃
@@ -0,0 +1,59 @@
+package domain.user.state;
+
+import domain.card.Card;
+import domain.result.GameResult;
+import domain.user.Score;
+
+import java.util.List;
+
+public class Wait extends State {
+
+    public Wait(List<Card> cards) {
+        super(cards);
+    }
+
+    @Override
+    public GameResult findResult(State state) {
+        throw new IllegalStateException("현재 차례를 마치지 않아, 결과를 찾을 수 없습니다.");
+    }
+
+    @Override
+    protected boolean isBlackjack() {
+        return false;
+    }
+
+    @Override
+    protected boolean isBust() {
+        return false;
+    }
+
+    @Override
+    protected boolean isStay() {
+        return false;
+    }
+
+    @Override
+    public State toStay() {
+        return new Stay(cards);
+    }
+
+    @Override
+    public State findNextState() {
+        Score score = this.calculateScore();
+        if (score.isBiggerThan(BLACKJACK_SCORE)) {
+            return new Bust(cards);
+        }
+        if (score.isSame(BLACKJACK_SCORE) && this.isInitialCards()) {
+            return new Blackjack(cards);
+        }
+        if (score.isSame(BLACKJACK_SCORE)) {
+            return new Stay(cards);
+        }
+        return new Wait(cards);
+    }
+
+    @Override
+    public boolean isEnded() {
+        return false;
+    }
+}

리뷰: [나무위키 - 블랙잭](https://namu.wiki/w/%EB%B8%94%EB%9E%99%EC%9E%AD(%EC%B9%B4%EB%93%9C%EA%B2%8C%EC%9E%84)#s-4.3)에 따르면 `아직 턴을 마치지 않은 상태`를 `HIT` 이라고 부른다고 합니다. 

Wait 상태가 `게임을 시작하기 전`의 상태를 의미하는 줄 알았는데, 코드를 쭉 보니까 아닌 것 같더라구요? 👀 
Wait보다는 Hit이 더 적절한 네이밍인 것 같다고 생각합니다. 재홍님은 어떻게 생각하시나요? 😃