From c05e861668dfbee6a6c17c1bfc1de7b7077580b4 Mon Sep 17 00:00:00 2001 From: JongHyunJung Date: Tue, 31 Oct 2023 15:25:08 +0900 Subject: [PATCH 01/44] =?UTF-8?q?docs:=20=EA=B5=AC=ED=98=84=20=EA=B8=B0?= =?UTF-8?q?=EB=8A=A5=20=EB=AA=A9=EB=A1=9D=20=EC=83=9D=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/README.md | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/docs/README.md b/docs/README.md index e69de29bb2d..01b08baaea4 100644 --- a/docs/README.md +++ b/docs/README.md @@ -0,0 +1,29 @@ +# 구현 기능 목록 + +## 기능 + +* [ ] 0부터 9 사이에 무작위 값을 구한 후 무작위 값이 4 이상일 경우 전진 + +## 입력 + +* [ ] 각 자동차 이름 부여 + * 이름은 5자 이하만 가능 + * 쉽표(,)를 기준 으로 자동차 이름 구분 +* [ ] 자동자 이동 횟수 + +## 출력 + +* [ ] 게임 시작 문구 출력 +* [ ] 각 차수별 실행 결과 출력 + * 자동차 이름과 함께 전진 하는 자동차 출력 +* [ ] 최종 우승자 안내 문구 + * 공동 우승일 경우 쉼표를 이용 하여 구분 + +## 예외 + +### 사용자 숫자 + +* [ ] 이름이 5자리 이하가 아닐시 예외 +* [ ] 0부터 9까지의 수가 아닐시 예외 + +## 🔨 리팩토링 목록 \ No newline at end of file From 597094fdf928f758ac67bacbc914105c7918da2d Mon Sep 17 00:00:00 2001 From: JongHyunJung Date: Tue, 31 Oct 2023 21:20:01 +0900 Subject: [PATCH 02/44] =?UTF-8?q?feat:=20=EA=B2=BD=EC=A3=BC=ED=95=A0=20?= =?UTF-8?q?=EC=9E=90=EB=8F=99=EC=B0=A8=20=EC=9D=B4=EB=A6=84=20=EC=9E=85?= =?UTF-8?q?=EB=A0=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/README.md | 10 +++++----- src/main/java/racingcar/Application.java | 6 +++++- .../controller/RacingCarController.java | 16 ++++++++++++++++ src/main/java/racingcar/view/InputView.java | 15 +++++++++++++++ 4 files changed, 41 insertions(+), 6 deletions(-) create mode 100644 src/main/java/racingcar/controller/RacingCarController.java create mode 100644 src/main/java/racingcar/view/InputView.java diff --git a/docs/README.md b/docs/README.md index 01b08baaea4..ada4f9b9bdd 100644 --- a/docs/README.md +++ b/docs/README.md @@ -2,18 +2,18 @@ ## 기능 -* [ ] 0부터 9 사이에 무작위 값을 구한 후 무작위 값이 4 이상일 경우 전진 +* [ ] 0부터 9 사이에 무작위 값 생성 +* [ ] 무작위 값이 4 이상일 경우 전진 ## 입력 -* [ ] 각 자동차 이름 부여 - * 이름은 5자 이하만 가능 +* [x] 각 자동차 이름 입력 + * 이름은 5자 이하 * 쉽표(,)를 기준 으로 자동차 이름 구분 -* [ ] 자동자 이동 횟수 +* [ ] 자동자 이동 횟수 입력 ## 출력 -* [ ] 게임 시작 문구 출력 * [ ] 각 차수별 실행 결과 출력 * 자동차 이름과 함께 전진 하는 자동차 출력 * [ ] 최종 우승자 안내 문구 diff --git a/src/main/java/racingcar/Application.java b/src/main/java/racingcar/Application.java index a17a52e7242..1dea6d60e15 100644 --- a/src/main/java/racingcar/Application.java +++ b/src/main/java/racingcar/Application.java @@ -1,7 +1,11 @@ package racingcar; +import racingcar.controller.RacingCarController; +import racingcar.view.InputView; + public class Application { public static void main(String[] args) { - // TODO: 프로그램 구현 + RacingCarController racingCarController = new RacingCarController(new InputView()); + racingCarController.run(); } } diff --git a/src/main/java/racingcar/controller/RacingCarController.java b/src/main/java/racingcar/controller/RacingCarController.java new file mode 100644 index 00000000000..be5a0270c3b --- /dev/null +++ b/src/main/java/racingcar/controller/RacingCarController.java @@ -0,0 +1,16 @@ +package racingcar.controller; + +import racingcar.view.InputView; + +public class RacingCarController { + final InputView inputView; + + public RacingCarController(InputView inputView){ + this.inputView = inputView; + } + + public void run(){ + String cars = inputView.readRaceCarNames(); + String[] names = cars.split(","); + } +} diff --git a/src/main/java/racingcar/view/InputView.java b/src/main/java/racingcar/view/InputView.java new file mode 100644 index 00000000000..1a9768c5eb6 --- /dev/null +++ b/src/main/java/racingcar/view/InputView.java @@ -0,0 +1,15 @@ +package racingcar.view; +import camp.nextstep.edu.missionutils.Console; + +public class InputView { + private static final String ENTER_CAR_NAME = "경주할 자동차 이름을 입력 하세요.(이름은 쉼표(,) 기준 으로 구분)"; + + public String readRaceCarNames() { + System.out.println(ENTER_CAR_NAME); + return readLine(); + } + + protected String readLine(){ + return Console.readLine(); + } +} From 539481d540856d0b82931d90d7e6e28c641a3634 Mon Sep 17 00:00:00 2001 From: JongHyunJung Date: Tue, 31 Oct 2023 21:29:28 +0900 Subject: [PATCH 03/44] =?UTF-8?q?feat:=20=EC=9E=90=EB=8F=99=EC=B0=A8=20?= =?UTF-8?q?=EC=9D=B4=EB=8F=99=20=ED=9A=9F=EC=88=98=20=EC=9E=85=EB=A0=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/README.md | 2 +- src/main/java/racingcar/controller/RacingCarController.java | 1 + src/main/java/racingcar/view/InputView.java | 6 ++++++ 3 files changed, 8 insertions(+), 1 deletion(-) diff --git a/docs/README.md b/docs/README.md index ada4f9b9bdd..f247f062bda 100644 --- a/docs/README.md +++ b/docs/README.md @@ -10,7 +10,7 @@ * [x] 각 자동차 이름 입력 * 이름은 5자 이하 * 쉽표(,)를 기준 으로 자동차 이름 구분 -* [ ] 자동자 이동 횟수 입력 +* [x] 자동자 이동 횟수 입력 ## 출력 diff --git a/src/main/java/racingcar/controller/RacingCarController.java b/src/main/java/racingcar/controller/RacingCarController.java index be5a0270c3b..1bdd6387ca3 100644 --- a/src/main/java/racingcar/controller/RacingCarController.java +++ b/src/main/java/racingcar/controller/RacingCarController.java @@ -12,5 +12,6 @@ public RacingCarController(InputView inputView){ public void run(){ String cars = inputView.readRaceCarNames(); String[] names = cars.split(","); + Integer round = Integer.parseInt(inputView.readRaceRound()); } } diff --git a/src/main/java/racingcar/view/InputView.java b/src/main/java/racingcar/view/InputView.java index 1a9768c5eb6..e8ca39a6d84 100644 --- a/src/main/java/racingcar/view/InputView.java +++ b/src/main/java/racingcar/view/InputView.java @@ -3,12 +3,18 @@ public class InputView { private static final String ENTER_CAR_NAME = "경주할 자동차 이름을 입력 하세요.(이름은 쉼표(,) 기준 으로 구분)"; + private static final String ENTER_RACE_ROUND = "시도할 회수는 몇 회 인가요?"; public String readRaceCarNames() { System.out.println(ENTER_CAR_NAME); return readLine(); } + public String readRaceRound() { + System.out.println(ENTER_RACE_ROUND); + return readLine(); + } + protected String readLine(){ return Console.readLine(); } From 4f617ff9fc94e5745dddb0b27a6c2d50eef2ac22 Mon Sep 17 00:00:00 2001 From: JongHyunJung Date: Tue, 31 Oct 2023 21:46:55 +0900 Subject: [PATCH 04/44] =?UTF-8?q?feat:=200=EB=B6=80=ED=84=B0=209=20?= =?UTF-8?q?=EC=82=AC=EC=9D=B4=EC=97=90=20=EB=AC=B4=EC=9E=91=EC=9C=84=20?= =?UTF-8?q?=EA=B0=92=20=EC=83=9D=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/README.md | 2 +- src/main/java/racingcar/type/PlayType.java | 12 ++++++++++++ .../java/racingcar/util/PickRandomNumber.java | 14 ++++++++++++++ .../racingcar/util/PickRandomNumberTest.java | 16 ++++++++++++++++ 4 files changed, 43 insertions(+), 1 deletion(-) create mode 100644 src/main/java/racingcar/type/PlayType.java create mode 100644 src/main/java/racingcar/util/PickRandomNumber.java create mode 100644 src/test/java/racingcar/util/PickRandomNumberTest.java diff --git a/docs/README.md b/docs/README.md index f247f062bda..7b2b4905b46 100644 --- a/docs/README.md +++ b/docs/README.md @@ -2,7 +2,7 @@ ## 기능 -* [ ] 0부터 9 사이에 무작위 값 생성 +* [x] 0부터 9 사이에 무작위 값 생성 * [ ] 무작위 값이 4 이상일 경우 전진 ## 입력 diff --git a/src/main/java/racingcar/type/PlayType.java b/src/main/java/racingcar/type/PlayType.java new file mode 100644 index 00000000000..563801d62e7 --- /dev/null +++ b/src/main/java/racingcar/type/PlayType.java @@ -0,0 +1,12 @@ +package racingcar.type; + +public enum PlayType { + MAX_NUM(9), + MIN_NUM(0); + + private final int playValue; + + PlayType(int playValue) { this.playValue = playValue; } + + public int getPlayValue() { return playValue; } +} diff --git a/src/main/java/racingcar/util/PickRandomNumber.java b/src/main/java/racingcar/util/PickRandomNumber.java new file mode 100644 index 00000000000..9c8458c6af2 --- /dev/null +++ b/src/main/java/racingcar/util/PickRandomNumber.java @@ -0,0 +1,14 @@ +package racingcar.util; + +import camp.nextstep.edu.missionutils.Randoms; + +import static racingcar.type.PlayType.MAX_NUM; +import static racingcar.type.PlayType.MIN_NUM; + +public class PickRandomNumber { + public PickRandomNumber(){} + + public static Integer generate(){ + return Randoms.pickNumberInRange(MIN_NUM.getPlayValue(), MAX_NUM.getPlayValue()); + } +} diff --git a/src/test/java/racingcar/util/PickRandomNumberTest.java b/src/test/java/racingcar/util/PickRandomNumberTest.java new file mode 100644 index 00000000000..93a81e6b4e8 --- /dev/null +++ b/src/test/java/racingcar/util/PickRandomNumberTest.java @@ -0,0 +1,16 @@ +package racingcar.util; + +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; + +import static org.assertj.core.api.Assertions.assertThat; +import static racingcar.type.PlayType.MAX_NUM; +import static racingcar.type.PlayType.MIN_NUM; + +public class PickRandomNumberTest { + @DisplayName("올바른 범위의 랜덤한 숫자 생성 테스트") + @Test + void checkPickRandomNumber() { + assertThat(PickRandomNumber.generate()).isBetween(MIN_NUM.getPlayValue(), MAX_NUM.getPlayValue()); + } +} From 2834cc848d651de43c08ec33e4d62f7ea27ae288 Mon Sep 17 00:00:00 2001 From: JongHyunJung Date: Tue, 31 Oct 2023 22:01:17 +0900 Subject: [PATCH 05/44] =?UTF-8?q?feat:=20=EB=AC=B4=EC=9E=91=EC=9C=84=20?= =?UTF-8?q?=EA=B0=92=EC=9D=B4=204=20=EC=9D=B4=EC=83=81=EC=9D=BC=20?= =?UTF-8?q?=EA=B2=BD=EC=9A=B0=20=EC=A0=84=EC=A7=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/README.md | 2 +- .../controller/RacingCarController.java | 28 ++++++++++++++++++- .../java/racingcar/service/GearShifting.java | 9 ++++++ 3 files changed, 37 insertions(+), 2 deletions(-) create mode 100644 src/main/java/racingcar/service/GearShifting.java diff --git a/docs/README.md b/docs/README.md index 7b2b4905b46..484ebd4cc87 100644 --- a/docs/README.md +++ b/docs/README.md @@ -3,7 +3,7 @@ ## 기능 * [x] 0부터 9 사이에 무작위 값 생성 -* [ ] 무작위 값이 4 이상일 경우 전진 +* [x] 무작위 값이 4 이상일 경우 전진 ## 입력 diff --git a/src/main/java/racingcar/controller/RacingCarController.java b/src/main/java/racingcar/controller/RacingCarController.java index 1bdd6387ca3..f45cfc219f1 100644 --- a/src/main/java/racingcar/controller/RacingCarController.java +++ b/src/main/java/racingcar/controller/RacingCarController.java @@ -1,7 +1,11 @@ package racingcar.controller; +import racingcar.service.GearShifting; import racingcar.view.InputView; +import java.util.HashMap; +import java.util.Map; + public class RacingCarController { final InputView inputView; @@ -12,6 +16,28 @@ public RacingCarController(InputView inputView){ public void run(){ String cars = inputView.readRaceCarNames(); String[] names = cars.split(","); - Integer round = Integer.parseInt(inputView.readRaceRound()); + int round = Integer.parseInt(inputView.readRaceRound()); + + // 각각의 racer 초기화 + Map position = new HashMap<>(); + for(String name: names){ + position.put(name, 0); + } + + for (int i=0 ; i < round ; i++){ + play(position); + } + } + + private void play(Map position) { + for (String name : position.keySet()){ + if (GearShifting.moveForward()) { + playMoveForward(position, name); + } + } + } + + private void playMoveForward(Map position, String name){ + position.put(name, position.get(name) + 1); } } diff --git a/src/main/java/racingcar/service/GearShifting.java b/src/main/java/racingcar/service/GearShifting.java new file mode 100644 index 00000000000..f7f535fc7a1 --- /dev/null +++ b/src/main/java/racingcar/service/GearShifting.java @@ -0,0 +1,9 @@ +package racingcar.service; + +import racingcar.util.PickRandomNumber; + +public class GearShifting { + public static boolean moveForward() { + return PickRandomNumber.generate() >= 4; + } +} From fe19f082c72550b567b54cc5ed5ccfee578afd45 Mon Sep 17 00:00:00 2001 From: JongHyunJung Date: Tue, 31 Oct 2023 22:11:03 +0900 Subject: [PATCH 06/44] =?UTF-8?q?feat:=20=EA=B0=81=20=EC=B0=A8=EC=88=98?= =?UTF-8?q?=EB=B3=84=20=EC=8B=A4=ED=96=89=20=EA=B2=B0=EA=B3=BC=20=EC=B6=9C?= =?UTF-8?q?=EB=A0=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/README.md | 2 +- src/main/java/racingcar/Application.java | 3 ++- .../controller/RacingCarController.java | 11 +++++++++-- src/main/java/racingcar/view/OutputView.java | 16 ++++++++++++++++ 4 files changed, 28 insertions(+), 4 deletions(-) create mode 100644 src/main/java/racingcar/view/OutputView.java diff --git a/docs/README.md b/docs/README.md index 484ebd4cc87..ce4717789b0 100644 --- a/docs/README.md +++ b/docs/README.md @@ -14,7 +14,7 @@ ## 출력 -* [ ] 각 차수별 실행 결과 출력 +* [x] 각 차수별 실행 결과 출력 * 자동차 이름과 함께 전진 하는 자동차 출력 * [ ] 최종 우승자 안내 문구 * 공동 우승일 경우 쉼표를 이용 하여 구분 diff --git a/src/main/java/racingcar/Application.java b/src/main/java/racingcar/Application.java index 1dea6d60e15..80c29a4c12d 100644 --- a/src/main/java/racingcar/Application.java +++ b/src/main/java/racingcar/Application.java @@ -2,10 +2,11 @@ import racingcar.controller.RacingCarController; import racingcar.view.InputView; +import racingcar.view.OutputView; public class Application { public static void main(String[] args) { - RacingCarController racingCarController = new RacingCarController(new InputView()); + RacingCarController racingCarController = new RacingCarController(new InputView(), new OutputView()); racingCarController.run(); } } diff --git a/src/main/java/racingcar/controller/RacingCarController.java b/src/main/java/racingcar/controller/RacingCarController.java index f45cfc219f1..d938ca6dd21 100644 --- a/src/main/java/racingcar/controller/RacingCarController.java +++ b/src/main/java/racingcar/controller/RacingCarController.java @@ -2,15 +2,18 @@ import racingcar.service.GearShifting; import racingcar.view.InputView; +import racingcar.view.OutputView; import java.util.HashMap; import java.util.Map; public class RacingCarController { - final InputView inputView; + private final InputView inputView; + private final OutputView outputView; - public RacingCarController(InputView inputView){ + public RacingCarController(InputView inputView, OutputView outputView){ this.inputView = inputView; + this.outputView = outputView; } public void run(){ @@ -24,8 +27,12 @@ public void run(){ position.put(name, 0); } + outputView.printExecution(); + // 라운드 별 각각의 레이서 결과 출력 for (int i=0 ; i < round ; i++){ play(position); + outputView.printResult(position); + System.out.println(); } } diff --git a/src/main/java/racingcar/view/OutputView.java b/src/main/java/racingcar/view/OutputView.java new file mode 100644 index 00000000000..ef041911ac2 --- /dev/null +++ b/src/main/java/racingcar/view/OutputView.java @@ -0,0 +1,16 @@ +package racingcar.view; + +import java.util.Map; + +public class OutputView { + private static final String ENTER_RACE_RESULT = "실행 결과"; + public void printExecution() { + System.out.println(ENTER_RACE_RESULT); + } + + public void printResult(Map position){ + for (String name : position.keySet()){ + System.out.println(name + " : " + "-".repeat(position.get(name))); + } + } +} From ef7d56b0b754df402a09ef8f092fd240d38a711b Mon Sep 17 00:00:00 2001 From: JongHyunJung Date: Tue, 31 Oct 2023 22:49:05 +0900 Subject: [PATCH 07/44] =?UTF-8?q?feat:=20=EC=B5=9C=EC=A2=85=20=EC=9A=B0?= =?UTF-8?q?=EC=8A=B9=EC=9E=90=20=EC=B6=9C=EB=A0=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/README.md | 2 +- .../controller/RacingCarController.java | 13 +++++++--- .../java/racingcar/service/JudgeWinner.java | 26 +++++++++++++++++++ .../{GearShifting.java => ShiftGear.java} | 2 +- src/main/java/racingcar/view/OutputView.java | 9 +++++++ 5 files changed, 46 insertions(+), 6 deletions(-) create mode 100644 src/main/java/racingcar/service/JudgeWinner.java rename src/main/java/racingcar/service/{GearShifting.java => ShiftGear.java} (85%) diff --git a/docs/README.md b/docs/README.md index ce4717789b0..4ad670cba63 100644 --- a/docs/README.md +++ b/docs/README.md @@ -16,7 +16,7 @@ * [x] 각 차수별 실행 결과 출력 * 자동차 이름과 함께 전진 하는 자동차 출력 -* [ ] 최종 우승자 안내 문구 +* [x] 최종 우승자 안내 문구 * 공동 우승일 경우 쉼표를 이용 하여 구분 ## 예외 diff --git a/src/main/java/racingcar/controller/RacingCarController.java b/src/main/java/racingcar/controller/RacingCarController.java index d938ca6dd21..f2f90ede3c5 100644 --- a/src/main/java/racingcar/controller/RacingCarController.java +++ b/src/main/java/racingcar/controller/RacingCarController.java @@ -1,10 +1,13 @@ package racingcar.controller; -import racingcar.service.GearShifting; +import racingcar.service.ShiftGear; +import racingcar.service.JudgeWinner; import racingcar.view.InputView; import racingcar.view.OutputView; import java.util.HashMap; +import java.util.LinkedHashMap; +import java.util.List; import java.util.Map; public class RacingCarController { @@ -18,11 +21,11 @@ public RacingCarController(InputView inputView, OutputView outputView){ public void run(){ String cars = inputView.readRaceCarNames(); - String[] names = cars.split(","); + List names = List.of(cars.split(",")); int round = Integer.parseInt(inputView.readRaceRound()); // 각각의 racer 초기화 - Map position = new HashMap<>(); + Map position = new LinkedHashMap<>(); for(String name: names){ position.put(name, 0); } @@ -34,11 +37,13 @@ public void run(){ outputView.printResult(position); System.out.println(); } + + outputView.printWinner(JudgeWinner.chooseWinner(position)); } private void play(Map position) { for (String name : position.keySet()){ - if (GearShifting.moveForward()) { + if (ShiftGear.moveForward()) { playMoveForward(position, name); } } diff --git a/src/main/java/racingcar/service/JudgeWinner.java b/src/main/java/racingcar/service/JudgeWinner.java new file mode 100644 index 00000000000..046c95cb6e0 --- /dev/null +++ b/src/main/java/racingcar/service/JudgeWinner.java @@ -0,0 +1,26 @@ +package racingcar.service; + +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + +public class JudgeWinner { + private JudgeWinner() {} + + public static List chooseWinner(Map position){ + int winnerPosition = calculatePosition(position); + return position.keySet().stream() + .filter(name -> isWinner(position.get(name), winnerPosition)) + .collect(Collectors.toList()); + } + + private static Integer calculatePosition(Map position){ + return position.values().stream() + .max(Integer::compare) + .orElse(0); + } + + private static boolean isWinner(int racerPosition, int winnerPosition){ + return racerPosition == winnerPosition; + } +} diff --git a/src/main/java/racingcar/service/GearShifting.java b/src/main/java/racingcar/service/ShiftGear.java similarity index 85% rename from src/main/java/racingcar/service/GearShifting.java rename to src/main/java/racingcar/service/ShiftGear.java index f7f535fc7a1..dc10403b857 100644 --- a/src/main/java/racingcar/service/GearShifting.java +++ b/src/main/java/racingcar/service/ShiftGear.java @@ -2,7 +2,7 @@ import racingcar.util.PickRandomNumber; -public class GearShifting { +public class ShiftGear { public static boolean moveForward() { return PickRandomNumber.generate() >= 4; } diff --git a/src/main/java/racingcar/view/OutputView.java b/src/main/java/racingcar/view/OutputView.java index ef041911ac2..3b4f3334b2f 100644 --- a/src/main/java/racingcar/view/OutputView.java +++ b/src/main/java/racingcar/view/OutputView.java @@ -1,5 +1,6 @@ package racingcar.view; +import java.util.List; import java.util.Map; public class OutputView { @@ -13,4 +14,12 @@ public void printResult(Map position){ System.out.println(name + " : " + "-".repeat(position.get(name))); } } + + public void printWinner(List winner){ + System.out.println("최종 우승자 : " + formatted(winner)); + } + + private String formatted(List winner){ + return String.join(", ", winner); + } } From fb596c5bce5924bd35398e110245fa37709511bb Mon Sep 17 00:00:00 2001 From: JongHyunJung Date: Wed, 1 Nov 2023 01:37:10 +0900 Subject: [PATCH 08/44] =?UTF-8?q?refactor:=20=EC=89=BC=ED=91=9C=20?= =?UTF-8?q?=EA=B3=B5=EB=B0=B1=20=EC=A0=9C=EA=B1=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/racingcar/controller/RacingCarController.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/main/java/racingcar/controller/RacingCarController.java b/src/main/java/racingcar/controller/RacingCarController.java index f2f90ede3c5..9af7d13c50f 100644 --- a/src/main/java/racingcar/controller/RacingCarController.java +++ b/src/main/java/racingcar/controller/RacingCarController.java @@ -21,7 +21,8 @@ public RacingCarController(InputView inputView, OutputView outputView){ public void run(){ String cars = inputView.readRaceCarNames(); - List names = List.of(cars.split(",")); + String resultCars = cars.replaceAll(" ", ""); + List names = List.of(resultCars.split(",")); int round = Integer.parseInt(inputView.readRaceRound()); // 각각의 racer 초기화 From 57d28ba8a3be7446927db7de65b880e35ba2288a Mon Sep 17 00:00:00 2001 From: JongHyunJung Date: Thu, 2 Nov 2023 19:08:52 +0900 Subject: [PATCH 09/44] =?UTF-8?q?feat:=20=EA=B2=BD=EC=A3=BC=ED=95=A0=20?= =?UTF-8?q?=EC=9E=90=EB=8F=99=EC=B0=A8=20=EC=9D=B4=EB=A6=84=EC=9D=B4=201?= =?UTF-8?q?=20=EC=9D=B4=EC=83=81=205=20=EC=9D=B4=ED=95=98=EA=B0=80=20?= =?UTF-8?q?=EC=95=84=EB=8B=8C=20=EA=B2=BD=EC=9A=B0=20=EC=98=88=EC=99=B8=20?= =?UTF-8?q?=EB=B0=9C=EC=83=9D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/README.md | 6 +++- src/main/java/racingcar/model/Car.java | 31 +++++++++++++++++++ .../java/racingcar/util/ValidateLength.java | 12 +++++++ src/test/java/racingcar/model/CarTest.java | 17 ++++++++++ 4 files changed, 65 insertions(+), 1 deletion(-) create mode 100644 src/main/java/racingcar/model/Car.java create mode 100644 src/main/java/racingcar/util/ValidateLength.java create mode 100644 src/test/java/racingcar/model/CarTest.java diff --git a/docs/README.md b/docs/README.md index 4ad670cba63..c9e0e84e3f6 100644 --- a/docs/README.md +++ b/docs/README.md @@ -19,7 +19,11 @@ * [x] 최종 우승자 안내 문구 * 공동 우승일 경우 쉼표를 이용 하여 구분 -## 예외 +## 예외 사항 +* [ ] 경주할 자동차 없는 경우 +* [x] 경주할 자동차 이름이 1 이상 5 이하가 아닌 경우 +* [ ] 경주할 자동차 구분자 "," 가 아닌 경우 +* [ ] 시도할 횟수가 자연수 아닌 경우 ### 사용자 숫자 diff --git a/src/main/java/racingcar/model/Car.java b/src/main/java/racingcar/model/Car.java new file mode 100644 index 00000000000..fac2800e1ae --- /dev/null +++ b/src/main/java/racingcar/model/Car.java @@ -0,0 +1,31 @@ +package racingcar.model; + +import racingcar.service.ShiftGear; +import racingcar.util.ValidateLength; + +public class Car { + private static final String MARK = "-"; + private static String name; + private int currentPosition; + + public Car(String name){ + validateName(name); + this.name = name; + this.currentPosition = 0; + } + + public void move() { + if (ShiftGear.moveForward()){ + currentPosition++; + } + } + + @Override + public String toString(){ + return this.name + " : " + MARK.repeat(this.currentPosition); + } + + private void validateName(String name){ + ValidateLength.check(5, name); + } +} diff --git a/src/main/java/racingcar/util/ValidateLength.java b/src/main/java/racingcar/util/ValidateLength.java new file mode 100644 index 00000000000..4b89996f48d --- /dev/null +++ b/src/main/java/racingcar/util/ValidateLength.java @@ -0,0 +1,12 @@ +package racingcar.util; + +public class ValidateLength { + public ValidateLength(){} + + public static void check(int max, String value){ + if(1 < value.length() || value.length() > max){ + throw new IllegalArgumentException(); + } + } + +} diff --git a/src/test/java/racingcar/model/CarTest.java b/src/test/java/racingcar/model/CarTest.java new file mode 100644 index 00000000000..946497b8b7a --- /dev/null +++ b/src/test/java/racingcar/model/CarTest.java @@ -0,0 +1,17 @@ +package racingcar.model; + +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.ValueSource; + +import static org.assertj.core.api.Assertions.assertThatThrownBy; + +public class CarTest { + @DisplayName("자동차 이름의 길이가 잘못된 경우 예외 발생") + @ParameterizedTest(name = "{displayName} value = {0}") + @ValueSource(strings = {"soul", "bb", "안 녕"}) + void checkValidateLength(String name){ + assertThatThrownBy(() -> new Car(name)) + .isInstanceOf(IllegalArgumentException.class); + } +} From 3b32b472174cd13d70bb931902c84a475f94356c Mon Sep 17 00:00:00 2001 From: JongHyunJung Date: Thu, 2 Nov 2023 20:00:55 +0900 Subject: [PATCH 10/44] =?UTF-8?q?feat:=20=EA=B2=BD=EC=A3=BC=ED=95=A0=20?= =?UTF-8?q?=EC=9E=90=EB=8F=99=EC=B0=A8=20=EC=97=86=EB=8A=94=20=EA=B2=BD?= =?UTF-8?q?=EC=9A=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/README.md | 2 +- src/main/java/racingcar/model/Racer.java | 48 +++++++++++++++++++ .../java/racingcar/util/ValidateSize.java | 13 +++++ src/test/java/racingcar/model/RacerTest.java | 19 ++++++++ 4 files changed, 81 insertions(+), 1 deletion(-) create mode 100644 src/main/java/racingcar/model/Racer.java create mode 100644 src/main/java/racingcar/util/ValidateSize.java create mode 100644 src/test/java/racingcar/model/RacerTest.java diff --git a/docs/README.md b/docs/README.md index c9e0e84e3f6..2db3d534a80 100644 --- a/docs/README.md +++ b/docs/README.md @@ -20,7 +20,7 @@ * 공동 우승일 경우 쉼표를 이용 하여 구분 ## 예외 사항 -* [ ] 경주할 자동차 없는 경우 +* [x] 경주할 자동차 없는 경우 * [x] 경주할 자동차 이름이 1 이상 5 이하가 아닌 경우 * [ ] 경주할 자동차 구분자 "," 가 아닌 경우 * [ ] 시도할 횟수가 자연수 아닌 경우 diff --git a/src/main/java/racingcar/model/Racer.java b/src/main/java/racingcar/model/Racer.java new file mode 100644 index 00000000000..e488add1f80 --- /dev/null +++ b/src/main/java/racingcar/model/Racer.java @@ -0,0 +1,48 @@ +package racingcar.model; + +import racingcar.util.ValidateSize; + +import java.util.Arrays; +import java.util.List; + +public class Racer { + public static final String SEPERATOR = ","; + private final List racer; + public Racer(String name) { + validateSize(name); + this.racer = Arrays.stream(name.split(SEPERATOR)) + .map(Car::new) + .toList(); + } + + // TODO: 메서드 위치 고민 해보기 + public void play(){ + racer.forEach(Car::move); + } + + @Override + public String toString(){ + StringBuilder stringBuilder = new StringBuilder(); + for (Car car : racer){ + stringBuilder.append(car.toString()).append("\n"); + } + return stringBuilder.toString(); + } + + @Override + public boolean equals(Object obj){ + if (this == obj){ + return true; + } + + if (!(obj instanceof Racer target)){ + return false; + } + + return racer.equals(target.racer); + } + + private void validateSize(String name){ + ValidateSize.check(name); + } +} diff --git a/src/main/java/racingcar/util/ValidateSize.java b/src/main/java/racingcar/util/ValidateSize.java new file mode 100644 index 00000000000..ff00dd8e868 --- /dev/null +++ b/src/main/java/racingcar/util/ValidateSize.java @@ -0,0 +1,13 @@ +package racingcar.util; + +import static racingcar.model.Racer.SEPERATOR; + +public class ValidateSize { + public ValidateSize(){} + + public static void check(String value){ + if(value == null || value.split(SEPERATOR).length == 0){ + throw new IllegalArgumentException("참가자가 없습니다"); + } + } +} diff --git a/src/test/java/racingcar/model/RacerTest.java b/src/test/java/racingcar/model/RacerTest.java new file mode 100644 index 00000000000..da56bbe8927 --- /dev/null +++ b/src/test/java/racingcar/model/RacerTest.java @@ -0,0 +1,19 @@ +package racingcar.model; + +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.NullSource; +import org.junit.jupiter.params.provider.ValueSource; + +import static org.assertj.core.api.Assertions.assertThatThrownBy; + +public class RacerTest { + @DisplayName("참가자가 없는 경우 예외 발생") + @ParameterizedTest + @NullSource + @ValueSource(strings = {""}) + void checkRacer(String value){ + assertThatThrownBy(() -> new Racer(value)) + .isInstanceOf(IllegalArgumentException.class); + } +} From 08a94c805ffb526312cbf777f0c9b2a71c7be77f Mon Sep 17 00:00:00 2001 From: JongHyunJung Date: Thu, 2 Nov 2023 20:59:55 +0900 Subject: [PATCH 11/44] =?UTF-8?q?refactor:=20Car,=20Racer=201=EA=B8=89=20C?= =?UTF-8?q?ollection=20=EC=A0=81=EC=9A=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../controller/RacingCarController.java | 48 ++++++++++--------- src/main/java/racingcar/model/Car.java | 36 ++++++++++++-- src/main/java/racingcar/model/Racer.java | 20 ++++++-- .../java/racingcar/util/ValidateLength.java | 12 ----- .../java/racingcar/util/ValidateSize.java | 13 ----- src/main/java/racingcar/view/OutputView.java | 21 ++++---- src/test/java/racingcar/model/RacerTest.java | 2 +- 7 files changed, 85 insertions(+), 67 deletions(-) delete mode 100644 src/main/java/racingcar/util/ValidateLength.java delete mode 100644 src/main/java/racingcar/util/ValidateSize.java diff --git a/src/main/java/racingcar/controller/RacingCarController.java b/src/main/java/racingcar/controller/RacingCarController.java index 9af7d13c50f..44fc1d577f0 100644 --- a/src/main/java/racingcar/controller/RacingCarController.java +++ b/src/main/java/racingcar/controller/RacingCarController.java @@ -1,5 +1,6 @@ package racingcar.controller; +import racingcar.model.Racer; import racingcar.service.ShiftGear; import racingcar.service.JudgeWinner; import racingcar.view.InputView; @@ -20,37 +21,40 @@ public RacingCarController(InputView inputView, OutputView outputView){ } public void run(){ - String cars = inputView.readRaceCarNames(); - String resultCars = cars.replaceAll(" ", ""); - List names = List.of(resultCars.split(",")); +// String cars = inputView.readRaceCarNames(); +// String resultCars = cars.replaceAll(" ", ""); +// List names = List.of(resultCars.split(",")); + Racer racer = new Racer(inputView.readRaceCarNames()); int round = Integer.parseInt(inputView.readRaceRound()); // 각각의 racer 초기화 - Map position = new LinkedHashMap<>(); - for(String name: names){ - position.put(name, 0); - } +// Map position = new LinkedHashMap<>(); +// for(String name: names){ +// position.put(name, 0); +// } outputView.printExecution(); // 라운드 별 각각의 레이서 결과 출력 for (int i=0 ; i < round ; i++){ - play(position); - outputView.printResult(position); - System.out.println(); + racer.play(); + outputView.printResult(racer); +// play(position); +// outputView.printResult(position); +// System.out.println(); } - outputView.printWinner(JudgeWinner.chooseWinner(position)); + outputView.printWinner(racer.getWinner()); } - private void play(Map position) { - for (String name : position.keySet()){ - if (ShiftGear.moveForward()) { - playMoveForward(position, name); - } - } - } - - private void playMoveForward(Map position, String name){ - position.put(name, position.get(name) + 1); - } +// private void play(Map position) { +// for (String name : position.keySet()){ +// if (ShiftGear.moveForward()) { +// playMoveForward(position, name); +// } +// } +// } + +// private void playMoveForward(Map position, String name){ +// position.put(name, position.get(name) + 1); +// } } diff --git a/src/main/java/racingcar/model/Car.java b/src/main/java/racingcar/model/Car.java index fac2800e1ae..ce701922c64 100644 --- a/src/main/java/racingcar/model/Car.java +++ b/src/main/java/racingcar/model/Car.java @@ -1,12 +1,11 @@ package racingcar.model; import racingcar.service.ShiftGear; -import racingcar.util.ValidateLength; -public class Car { +public class Car implements Comparable { private static final String MARK = "-"; - private static String name; - private int currentPosition; + private final String name; + private Integer currentPosition; public Car(String name){ validateName(name); @@ -20,12 +19,39 @@ public void move() { } } + public String getName() { + return this.name; + } + @Override public String toString(){ return this.name + " : " + MARK.repeat(this.currentPosition); } + @Override + public boolean equals(Object obj){ + if (this == obj){ + return true; + } + + if(!(obj instanceof Car car)){ + return false; + } + return this.currentPosition.equals(car.currentPosition); + } + + @Override + public int compareTo(Car car) { + return this.currentPosition - car.currentPosition; + } + private void validateName(String name){ - ValidateLength.check(5, name); + validateLength(name); + } + + private void validateLength(String value){ + if(value.isEmpty() || value.length() > 5){ + throw new IllegalArgumentException(); + } } } diff --git a/src/main/java/racingcar/model/Racer.java b/src/main/java/racingcar/model/Racer.java index e488add1f80..3c4764a4999 100644 --- a/src/main/java/racingcar/model/Racer.java +++ b/src/main/java/racingcar/model/Racer.java @@ -1,15 +1,14 @@ package racingcar.model; -import racingcar.util.ValidateSize; - import java.util.Arrays; import java.util.List; +import java.util.stream.Collectors; public class Racer { public static final String SEPERATOR = ","; private final List racer; public Racer(String name) { - validateSize(name); + validate(name); this.racer = Arrays.stream(name.split(SEPERATOR)) .map(Car::new) .toList(); @@ -20,6 +19,11 @@ public void play(){ racer.forEach(Car::move); } + public String getWinner() { + Car winner = racer.stream().max(Car::compareTo).orElseThrow(); + return racer.stream().filter(winner::equals).map(Car::getName).collect(Collectors.joining(",")); + } + @Override public String toString(){ StringBuilder stringBuilder = new StringBuilder(); @@ -42,7 +46,13 @@ public boolean equals(Object obj){ return racer.equals(target.racer); } - private void validateSize(String name){ - ValidateSize.check(name); + private void validate(String name){ + validateSize(name); + } + + private void validateSize(String value){ + if (value == null || value.split(SEPERATOR).length == 0){ + throw new IllegalArgumentException("참가자 없음"); + } } } diff --git a/src/main/java/racingcar/util/ValidateLength.java b/src/main/java/racingcar/util/ValidateLength.java deleted file mode 100644 index 4b89996f48d..00000000000 --- a/src/main/java/racingcar/util/ValidateLength.java +++ /dev/null @@ -1,12 +0,0 @@ -package racingcar.util; - -public class ValidateLength { - public ValidateLength(){} - - public static void check(int max, String value){ - if(1 < value.length() || value.length() > max){ - throw new IllegalArgumentException(); - } - } - -} diff --git a/src/main/java/racingcar/util/ValidateSize.java b/src/main/java/racingcar/util/ValidateSize.java deleted file mode 100644 index ff00dd8e868..00000000000 --- a/src/main/java/racingcar/util/ValidateSize.java +++ /dev/null @@ -1,13 +0,0 @@ -package racingcar.util; - -import static racingcar.model.Racer.SEPERATOR; - -public class ValidateSize { - public ValidateSize(){} - - public static void check(String value){ - if(value == null || value.split(SEPERATOR).length == 0){ - throw new IllegalArgumentException("참가자가 없습니다"); - } - } -} diff --git a/src/main/java/racingcar/view/OutputView.java b/src/main/java/racingcar/view/OutputView.java index 3b4f3334b2f..c232cc09cf0 100644 --- a/src/main/java/racingcar/view/OutputView.java +++ b/src/main/java/racingcar/view/OutputView.java @@ -1,5 +1,7 @@ package racingcar.view; +import racingcar.model.Racer; + import java.util.List; import java.util.Map; @@ -9,17 +11,18 @@ public void printExecution() { System.out.println(ENTER_RACE_RESULT); } - public void printResult(Map position){ - for (String name : position.keySet()){ - System.out.println(name + " : " + "-".repeat(position.get(name))); - } + public void printResult(Racer racer){ +// for (String name : position.keySet()){ +// System.out.println(name + " : " + "-".repeat(position.get(name))); +// } + System.out.println(racer.toString()); } - public void printWinner(List winner){ - System.out.println("최종 우승자 : " + formatted(winner)); + public void printWinner(String winner){ + System.out.println("최종 우승자 : " + winner); } - private String formatted(List winner){ - return String.join(", ", winner); - } +// private String formatted(List winner){ +// return String.join(", ", winner); +// } } diff --git a/src/test/java/racingcar/model/RacerTest.java b/src/test/java/racingcar/model/RacerTest.java index da56bbe8927..4e741e040d2 100644 --- a/src/test/java/racingcar/model/RacerTest.java +++ b/src/test/java/racingcar/model/RacerTest.java @@ -11,7 +11,7 @@ public class RacerTest { @DisplayName("참가자가 없는 경우 예외 발생") @ParameterizedTest @NullSource - @ValueSource(strings = {""}) + @ValueSource(strings = {"asdf"}) void checkRacer(String value){ assertThatThrownBy(() -> new Racer(value)) .isInstanceOf(IllegalArgumentException.class); From f6448cf06de44dd18721b85828f6ebd1592526d4 Mon Sep 17 00:00:00 2001 From: JongHyunJung Date: Sat, 4 Nov 2023 01:15:13 +0900 Subject: [PATCH 12/44] =?UTF-8?q?refactor:=20=EC=8B=9C=EB=8F=84=ED=95=A0?= =?UTF-8?q?=20=ED=9A=9F=EC=88=98=20(Round)=201=EA=B8=89=20=EC=BB=AC?= =?UTF-8?q?=EB=A0=89=EC=85=98=20=EC=A0=81=EC=9A=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/README.md | 7 ++-- .../controller/RacingCarController.java | 19 +++++----- src/main/java/racingcar/model/Round.java | 35 +++++++++++++++++++ src/test/java/racingcar/model/CarTest.java | 2 +- src/test/java/racingcar/model/RacerTest.java | 2 +- src/test/java/racingcar/model/RoundTest.java | 19 ++++++++++ 6 files changed, 70 insertions(+), 14 deletions(-) create mode 100644 src/main/java/racingcar/model/Round.java create mode 100644 src/test/java/racingcar/model/RoundTest.java diff --git a/docs/README.md b/docs/README.md index 2db3d534a80..3e6b3089060 100644 --- a/docs/README.md +++ b/docs/README.md @@ -23,11 +23,14 @@ * [x] 경주할 자동차 없는 경우 * [x] 경주할 자동차 이름이 1 이상 5 이하가 아닌 경우 * [ ] 경주할 자동차 구분자 "," 가 아닌 경우 -* [ ] 시도할 횟수가 자연수 아닌 경우 +* [x] 시도할 횟수가 자연수 아닌 경우 ### 사용자 숫자 * [ ] 이름이 5자리 이하가 아닐시 예외 * [ ] 0부터 9까지의 수가 아닐시 예외 -## 🔨 리팩토링 목록 \ No newline at end of file +## 🔨 리팩토링 목록 +* [x] 1급 Collection 적용 +* [ ] 상수 사용 +* [ ] interface 활용 (메세지 던지기) \ No newline at end of file diff --git a/src/main/java/racingcar/controller/RacingCarController.java b/src/main/java/racingcar/controller/RacingCarController.java index 44fc1d577f0..370d184b62c 100644 --- a/src/main/java/racingcar/controller/RacingCarController.java +++ b/src/main/java/racingcar/controller/RacingCarController.java @@ -1,16 +1,10 @@ package racingcar.controller; import racingcar.model.Racer; -import racingcar.service.ShiftGear; -import racingcar.service.JudgeWinner; +import racingcar.model.Round; import racingcar.view.InputView; import racingcar.view.OutputView; -import java.util.HashMap; -import java.util.LinkedHashMap; -import java.util.List; -import java.util.Map; - public class RacingCarController { private final InputView inputView; private final OutputView outputView; @@ -25,7 +19,8 @@ public void run(){ // String resultCars = cars.replaceAll(" ", ""); // List names = List.of(resultCars.split(",")); Racer racer = new Racer(inputView.readRaceCarNames()); - int round = Integer.parseInt(inputView.readRaceRound()); +// int round = Integer.parseInt(inputView.readRaceRound()); + Round round = new Round(inputView.readRaceRound()); // 각각의 racer 초기화 // Map position = new LinkedHashMap<>(); @@ -35,13 +30,17 @@ public void run(){ outputView.printExecution(); // 라운드 별 각각의 레이서 결과 출력 - for (int i=0 ; i < round ; i++){ + while(round.isContinue()){ racer.play(); outputView.printResult(racer); + } +// for (int i=0 ; i < round ; i++){ +// racer.play(); +// outputView.printResult(racer); // play(position); // outputView.printResult(position); // System.out.println(); - } +// } outputView.printWinner(racer.getWinner()); } diff --git a/src/main/java/racingcar/model/Round.java b/src/main/java/racingcar/model/Round.java new file mode 100644 index 00000000000..878889e177a --- /dev/null +++ b/src/main/java/racingcar/model/Round.java @@ -0,0 +1,35 @@ +package racingcar.model; + +public class Round { + private Integer round; + + public Round(String round){ + validate(round); + this.round = Integer.parseInt(round); + } + + public Boolean isContinue(){ + if (round > 0){ + round --; + return true; + } + return false; + } + + private void validate(String value){ + validateType(value); + validateRange(value); + } + + private void validateType(String value){ + if (value != null && !value.matches("^[0-9]+")){ + throw new IllegalArgumentException(); + } + } + + private void validateRange(String value){ + if (0 >= Integer.parseInt(value)) { + throw new IllegalArgumentException(); + } + } +} diff --git a/src/test/java/racingcar/model/CarTest.java b/src/test/java/racingcar/model/CarTest.java index 946497b8b7a..6f320ccad96 100644 --- a/src/test/java/racingcar/model/CarTest.java +++ b/src/test/java/racingcar/model/CarTest.java @@ -6,7 +6,7 @@ import static org.assertj.core.api.Assertions.assertThatThrownBy; -public class CarTest { +class CarTest { @DisplayName("자동차 이름의 길이가 잘못된 경우 예외 발생") @ParameterizedTest(name = "{displayName} value = {0}") @ValueSource(strings = {"soul", "bb", "안 녕"}) diff --git a/src/test/java/racingcar/model/RacerTest.java b/src/test/java/racingcar/model/RacerTest.java index 4e741e040d2..95f2a57669b 100644 --- a/src/test/java/racingcar/model/RacerTest.java +++ b/src/test/java/racingcar/model/RacerTest.java @@ -7,7 +7,7 @@ import static org.assertj.core.api.Assertions.assertThatThrownBy; -public class RacerTest { +class RacerTest { @DisplayName("참가자가 없는 경우 예외 발생") @ParameterizedTest @NullSource diff --git a/src/test/java/racingcar/model/RoundTest.java b/src/test/java/racingcar/model/RoundTest.java new file mode 100644 index 00000000000..563f117c597 --- /dev/null +++ b/src/test/java/racingcar/model/RoundTest.java @@ -0,0 +1,19 @@ +package racingcar.model; + +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.NullSource; +import org.junit.jupiter.params.provider.ValueSource; + +import static org.assertj.core.api.Assertions.assertThatThrownBy; + +class RoundTest { + @DisplayName("잘못된 횟수 입력 테스트") + @ParameterizedTest(name = "{displayName}: {0}") + @ValueSource(strings = {"0", "-123", "akd", "", "-", "12a", " 1"}) + @NullSource + void checkInvalidRound(String value){ + assertThatThrownBy(() -> + new Round(value)).isInstanceOf(IllegalArgumentException.class); + } +} From cd16a9a3da9fbf028815b0814ee705d14ff4cfa0 Mon Sep 17 00:00:00 2001 From: JongHyunJung Date: Tue, 7 Nov 2023 14:22:32 +0900 Subject: [PATCH 13/44] =?UTF-8?q?refactor:=20=EC=83=81=EC=88=98=20?= =?UTF-8?q?=EC=82=AC=EC=9A=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/racingcar/model/Car.java | 5 ++++- src/main/java/racingcar/model/Racer.java | 6 +++++- src/main/java/racingcar/model/Round.java | 4 +++- src/main/java/racingcar/service/ShiftGear.java | 4 +++- src/main/java/racingcar/type/PlayType.java | 5 ++++- 5 files changed, 19 insertions(+), 5 deletions(-) diff --git a/src/main/java/racingcar/model/Car.java b/src/main/java/racingcar/model/Car.java index ce701922c64..dd828c02eac 100644 --- a/src/main/java/racingcar/model/Car.java +++ b/src/main/java/racingcar/model/Car.java @@ -2,6 +2,9 @@ import racingcar.service.ShiftGear; +import static racingcar.type.PlayType.MAX_LENGTH; +import static racingcar.type.PlayType.MIN_LENGTH; + public class Car implements Comparable { private static final String MARK = "-"; private final String name; @@ -50,7 +53,7 @@ private void validateName(String name){ } private void validateLength(String value){ - if(value.isEmpty() || value.length() > 5){ + if(MIN_LENGTH.getPlayValue() > value.length() || value.length() > MAX_LENGTH.getPlayValue()){ throw new IllegalArgumentException(); } } diff --git a/src/main/java/racingcar/model/Racer.java b/src/main/java/racingcar/model/Racer.java index 3c4764a4999..b002da23a2d 100644 --- a/src/main/java/racingcar/model/Racer.java +++ b/src/main/java/racingcar/model/Racer.java @@ -21,7 +21,11 @@ public void play(){ public String getWinner() { Car winner = racer.stream().max(Car::compareTo).orElseThrow(); - return racer.stream().filter(winner::equals).map(Car::getName).collect(Collectors.joining(",")); + + return racer.stream() + .filter(winner::equals) + .map(Car::getName) + .collect(Collectors.joining(SEPERATOR)); } @Override diff --git a/src/main/java/racingcar/model/Round.java b/src/main/java/racingcar/model/Round.java index 878889e177a..5af0b1ed3d2 100644 --- a/src/main/java/racingcar/model/Round.java +++ b/src/main/java/racingcar/model/Round.java @@ -2,12 +2,14 @@ public class Round { private Integer round; + public static final String ONLY_NUMBER = "^[0-9]+"; public Round(String round){ validate(round); this.round = Integer.parseInt(round); } + // TODO: 진행 중인지 확인 하는 것 뿐 아니라 감소도 함 public Boolean isContinue(){ if (round > 0){ round --; @@ -22,7 +24,7 @@ private void validate(String value){ } private void validateType(String value){ - if (value != null && !value.matches("^[0-9]+")){ + if (value != null && !value.matches(ONLY_NUMBER)){ throw new IllegalArgumentException(); } } diff --git a/src/main/java/racingcar/service/ShiftGear.java b/src/main/java/racingcar/service/ShiftGear.java index dc10403b857..3daf104ff55 100644 --- a/src/main/java/racingcar/service/ShiftGear.java +++ b/src/main/java/racingcar/service/ShiftGear.java @@ -2,8 +2,10 @@ import racingcar.util.PickRandomNumber; +import static racingcar.type.PlayType.MOVING_POSSIBILITY; + public class ShiftGear { public static boolean moveForward() { - return PickRandomNumber.generate() >= 4; + return PickRandomNumber.generate() >= MOVING_POSSIBILITY.getPlayValue(); } } diff --git a/src/main/java/racingcar/type/PlayType.java b/src/main/java/racingcar/type/PlayType.java index 563801d62e7..b6d11fc8668 100644 --- a/src/main/java/racingcar/type/PlayType.java +++ b/src/main/java/racingcar/type/PlayType.java @@ -1,8 +1,11 @@ package racingcar.type; public enum PlayType { + MAX_LENGTH(1), + MIN_LENGTH(5), MAX_NUM(9), - MIN_NUM(0); + MIN_NUM(0), + MOVING_POSSIBILITY(4); private final int playValue; From 7ee1cad418bb72f8ad11fd35dfbaffa235638f73 Mon Sep 17 00:00:00 2001 From: JongHyunJung Date: Tue, 7 Nov 2023 14:54:28 +0900 Subject: [PATCH 14/44] =?UTF-8?q?refactor:=20Interface=20=ED=86=B5?= =?UTF-8?q?=ED=95=9C=20Car=20=EA=B2=80=EC=A6=9D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/racingcar/model/Car.java | 30 +++++++++++-------- .../racingcar/validation/CarValidator.java | 24 +++++++++++++++ .../java/racingcar/validation/Validator.java | 7 +++++ .../validation/CarValidatorTest.java | 17 +++++++++++ 4 files changed, 66 insertions(+), 12 deletions(-) create mode 100644 src/main/java/racingcar/validation/CarValidator.java create mode 100644 src/main/java/racingcar/validation/Validator.java create mode 100644 src/test/java/racingcar/validation/CarValidatorTest.java diff --git a/src/main/java/racingcar/model/Car.java b/src/main/java/racingcar/model/Car.java index dd828c02eac..6bc8bc65989 100644 --- a/src/main/java/racingcar/model/Car.java +++ b/src/main/java/racingcar/model/Car.java @@ -1,9 +1,8 @@ package racingcar.model; import racingcar.service.ShiftGear; - -import static racingcar.type.PlayType.MAX_LENGTH; -import static racingcar.type.PlayType.MIN_LENGTH; +import racingcar.validation.CarValidator; +import racingcar.validation.Validator; public class Car implements Comparable { private static final String MARK = "-"; @@ -22,6 +21,13 @@ public void move() { } } + private void validateName(String value){ + Validator carValidator = new CarValidator(); + if(carValidator.support(Car.class)) { + carValidator.validate(value); + } + } + public String getName() { return this.name; } @@ -48,13 +54,13 @@ public int compareTo(Car car) { return this.currentPosition - car.currentPosition; } - private void validateName(String name){ - validateLength(name); - } - - private void validateLength(String value){ - if(MIN_LENGTH.getPlayValue() > value.length() || value.length() > MAX_LENGTH.getPlayValue()){ - throw new IllegalArgumentException(); - } - } +// private void validateName(String name){ +// validateLength(name); +// } +// +// private void validateLength(String value){ +// if(MIN_LENGTH.getPlayValue() > value.length() || value.length() > MAX_LENGTH.getPlayValue()){ +// throw new IllegalArgumentException(); +// } +// } } diff --git a/src/main/java/racingcar/validation/CarValidator.java b/src/main/java/racingcar/validation/CarValidator.java new file mode 100644 index 00000000000..d40d6fb4d01 --- /dev/null +++ b/src/main/java/racingcar/validation/CarValidator.java @@ -0,0 +1,24 @@ +package racingcar.validation; + +import racingcar.model.Car; + +import static racingcar.type.PlayType.MAX_LENGTH; +import static racingcar.type.PlayType.MIN_LENGTH; + +public class CarValidator implements Validator { + @Override + public boolean support(Class clazz) { + return clazz.isAssignableFrom(Car.class); + } + + @Override + public void validate(Object target) { + validateLength((String) target); + } + + private void validateLength(String value){ + if(MIN_LENGTH.getPlayValue() > value.length() || value.length() > MAX_LENGTH.getPlayValue()){ + throw new IllegalArgumentException(); + } + } +} diff --git a/src/main/java/racingcar/validation/Validator.java b/src/main/java/racingcar/validation/Validator.java new file mode 100644 index 00000000000..fd49b1a1e50 --- /dev/null +++ b/src/main/java/racingcar/validation/Validator.java @@ -0,0 +1,7 @@ +package racingcar.validation; + +public interface Validator { + boolean support(Class clazz); + + void validate(Object target); +} diff --git a/src/test/java/racingcar/validation/CarValidatorTest.java b/src/test/java/racingcar/validation/CarValidatorTest.java new file mode 100644 index 00000000000..ec07a7b77f5 --- /dev/null +++ b/src/test/java/racingcar/validation/CarValidatorTest.java @@ -0,0 +1,17 @@ +package racingcar.validation; + +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import racingcar.model.Car; + +import static org.assertj.core.api.Assertions.assertThat; + +public class CarValidatorTest { + private final CarValidator carValidator = new CarValidator(); + + @DisplayName("클래스 지원 테스트") + @Test + void checkSupport() { + assertThat(carValidator.support(Car.class)).isTrue(); + } +} From 1a0429ba7815b0be2e121cecac05b77eba6d4bbb Mon Sep 17 00:00:00 2001 From: JongHyunJung Date: Tue, 28 Nov 2023 18:46:11 +0900 Subject: [PATCH 15/44] =?UTF-8?q?refactor:=20Interface=20=ED=86=B5?= =?UTF-8?q?=ED=95=9C=20Racer=20=EA=B2=80=EC=A6=9D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/racingcar/model/Racer.java | 26 ++++++++++++------- src/main/java/racingcar/type/PlayType.java | 3 ++- .../racingcar/validation/CarValidator.java | 2 +- .../racingcar/validation/RacerValidator.java | 24 +++++++++++++++++ .../validation/CarValidatorTest.java | 3 ++- .../validation/RacerValidatorTest.java | 17 ++++++++++++ 6 files changed, 63 insertions(+), 12 deletions(-) create mode 100644 src/main/java/racingcar/validation/RacerValidator.java create mode 100644 src/test/java/racingcar/validation/RacerValidatorTest.java diff --git a/src/main/java/racingcar/model/Racer.java b/src/main/java/racingcar/model/Racer.java index b002da23a2d..705ef554050 100644 --- a/src/main/java/racingcar/model/Racer.java +++ b/src/main/java/racingcar/model/Racer.java @@ -1,5 +1,8 @@ package racingcar.model; +import racingcar.validation.RacerValidator; +import racingcar.validation.Validator; + import java.util.Arrays; import java.util.List; import java.util.stream.Collectors; @@ -19,6 +22,11 @@ public void play(){ racer.forEach(Car::move); } + private void validate(String value){ + Validator validator = new RacerValidator(); + validator.validate(value); + } + public String getWinner() { Car winner = racer.stream().max(Car::compareTo).orElseThrow(); @@ -50,13 +58,13 @@ public boolean equals(Object obj){ return racer.equals(target.racer); } - private void validate(String name){ - validateSize(name); - } - - private void validateSize(String value){ - if (value == null || value.split(SEPERATOR).length == 0){ - throw new IllegalArgumentException("참가자 없음"); - } - } +// private void validate(String name){ +// validateSize(name); +// } +// +// private void validateSize(String value){ +// if (value == null || value.split(SEPERATOR).length == 0){ +// throw new IllegalArgumentException("참가자 없음"); +// } +// } } diff --git a/src/main/java/racingcar/type/PlayType.java b/src/main/java/racingcar/type/PlayType.java index b6d11fc8668..34e45d749e4 100644 --- a/src/main/java/racingcar/type/PlayType.java +++ b/src/main/java/racingcar/type/PlayType.java @@ -5,7 +5,8 @@ public enum PlayType { MIN_LENGTH(5), MAX_NUM(9), MIN_NUM(0), - MOVING_POSSIBILITY(4); + MOVING_POSSIBILITY(4), + MIN_PARTICIPANT(1); private final int playValue; diff --git a/src/main/java/racingcar/validation/CarValidator.java b/src/main/java/racingcar/validation/CarValidator.java index d40d6fb4d01..5e883ab99d6 100644 --- a/src/main/java/racingcar/validation/CarValidator.java +++ b/src/main/java/racingcar/validation/CarValidator.java @@ -8,7 +8,7 @@ public class CarValidator implements Validator { @Override public boolean support(Class clazz) { - return clazz.isAssignableFrom(Car.class); + return Car.class.isAssignableFrom(clazz); } @Override diff --git a/src/main/java/racingcar/validation/RacerValidator.java b/src/main/java/racingcar/validation/RacerValidator.java new file mode 100644 index 00000000000..2b48177c701 --- /dev/null +++ b/src/main/java/racingcar/validation/RacerValidator.java @@ -0,0 +1,24 @@ +package racingcar.validation; + +import racingcar.model.Racer; + +import static racingcar.type.PlayType.MIN_PARTICIPANT; + +public class RacerValidator implements Validator { + public static final String SEPERATOR = ","; + @Override + public boolean support(Class clazz) { + return Racer.class.isAssignableFrom(clazz); + } + + @Override + public void validate(Object target) { + validateSize((String) target); + } + + public void validateSize(String value){ + if (value == null || value.split(SEPERATOR).length < MIN_PARTICIPANT.getPlayValue()) { + throw new IllegalArgumentException("참가자가 없습니다."); + } + } +} diff --git a/src/test/java/racingcar/validation/CarValidatorTest.java b/src/test/java/racingcar/validation/CarValidatorTest.java index ec07a7b77f5..ac1c6b5e9c5 100644 --- a/src/test/java/racingcar/validation/CarValidatorTest.java +++ b/src/test/java/racingcar/validation/CarValidatorTest.java @@ -7,11 +7,12 @@ import static org.assertj.core.api.Assertions.assertThat; public class CarValidatorTest { - private final CarValidator carValidator = new CarValidator(); +// private final CarValidator carValidator = new CarValidator(); @DisplayName("클래스 지원 테스트") @Test void checkSupport() { + Validator carValidator = new CarValidator(); assertThat(carValidator.support(Car.class)).isTrue(); } } diff --git a/src/test/java/racingcar/validation/RacerValidatorTest.java b/src/test/java/racingcar/validation/RacerValidatorTest.java new file mode 100644 index 00000000000..a119a386c68 --- /dev/null +++ b/src/test/java/racingcar/validation/RacerValidatorTest.java @@ -0,0 +1,17 @@ +package racingcar.validation; + +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import racingcar.model.Racer; + +import static org.assertj.core.api.Assertions.assertThat; + +public class RacerValidatorTest { + // TODO: 추후 검증기 모아 한 클래스 에서 테스트 + @DisplayName("클래스 지원 테스트") + @Test + void checkSupport(){ + Validator validator = new RacerValidator(); + assertThat(validator.support(Racer.class)).isTrue(); + } +} From 15e03894ded57f3b6944e5cff8162b5029a6aef8 Mon Sep 17 00:00:00 2001 From: JongHyunJung Date: Tue, 28 Nov 2023 18:56:49 +0900 Subject: [PATCH 16/44] =?UTF-8?q?refactor:=20Interface=20=ED=86=B5?= =?UTF-8?q?=ED=95=9C=20Round=20=EA=B2=80=EC=A6=9D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/racingcar/model/Round.java | 35 +++++++++++-------- .../racingcar/validation/RoundValidator.java | 32 +++++++++++++++++ .../validation/CarValidatorTest.java | 2 +- .../validation/RacerValidatorTest.java | 2 +- .../validation/RoundValidatorTest.java | 15 ++++++++ 5 files changed, 70 insertions(+), 16 deletions(-) create mode 100644 src/main/java/racingcar/validation/RoundValidator.java create mode 100644 src/test/java/racingcar/validation/RoundValidatorTest.java diff --git a/src/main/java/racingcar/model/Round.java b/src/main/java/racingcar/model/Round.java index 5af0b1ed3d2..12eb0f2c23f 100644 --- a/src/main/java/racingcar/model/Round.java +++ b/src/main/java/racingcar/model/Round.java @@ -1,8 +1,13 @@ package racingcar.model; +import racingcar.validation.RoundValidator; +import racingcar.validation.Validator; + +import static racingcar.type.PlayType.MAX_NUM; +import static racingcar.type.PlayType.MIN_NUM; + public class Round { private Integer round; - public static final String ONLY_NUMBER = "^[0-9]+"; public Round(String round){ validate(round); @@ -19,19 +24,21 @@ public Boolean isContinue(){ } private void validate(String value){ - validateType(value); - validateRange(value); + Validator validator = new RoundValidator(); + validator.validate(value); +// validateType(value); +// validateRange(value); } - private void validateType(String value){ - if (value != null && !value.matches(ONLY_NUMBER)){ - throw new IllegalArgumentException(); - } - } - - private void validateRange(String value){ - if (0 >= Integer.parseInt(value)) { - throw new IllegalArgumentException(); - } - } +// private void validateType(String value){ +// if (value != null && !value.matches(ONLY_NUMBER)){ +// throw new IllegalArgumentException(); +// } +// } +// +// private void validateRange(String value){ +// if (0 >= Integer.parseInt(value)) { +// throw new IllegalArgumentException(); +// } +// } } diff --git a/src/main/java/racingcar/validation/RoundValidator.java b/src/main/java/racingcar/validation/RoundValidator.java new file mode 100644 index 00000000000..d1367f3ce63 --- /dev/null +++ b/src/main/java/racingcar/validation/RoundValidator.java @@ -0,0 +1,32 @@ +package racingcar.validation; + +import racingcar.model.Round; + +import static racingcar.type.PlayType.MAX_NUM; +import static racingcar.type.PlayType.MIN_NUM; + +public class RoundValidator implements Validator { + public static final String VALID_RANGE = "^["+ MIN_NUM + "-" + MAX_NUM +"]+"; + @Override + public boolean support(Class clazz) { + return Round.class.isAssignableFrom(clazz); + } + + @Override + public void validate(Object target) { + validateType((String) target); + validateRange((String) target); + } + + private void validateType(String value){ + if (value != null && !value.matches(VALID_RANGE)){ + throw new IllegalArgumentException(); + } + } + + private void validateRange(String value){ + if (0 >= Integer.parseInt(value)) { + throw new IllegalArgumentException(); + } + } +} diff --git a/src/test/java/racingcar/validation/CarValidatorTest.java b/src/test/java/racingcar/validation/CarValidatorTest.java index ac1c6b5e9c5..ed2cc52a0fc 100644 --- a/src/test/java/racingcar/validation/CarValidatorTest.java +++ b/src/test/java/racingcar/validation/CarValidatorTest.java @@ -6,7 +6,7 @@ import static org.assertj.core.api.Assertions.assertThat; -public class CarValidatorTest { +class CarValidatorTest { // private final CarValidator carValidator = new CarValidator(); @DisplayName("클래스 지원 테스트") diff --git a/src/test/java/racingcar/validation/RacerValidatorTest.java b/src/test/java/racingcar/validation/RacerValidatorTest.java index a119a386c68..3a843f9d384 100644 --- a/src/test/java/racingcar/validation/RacerValidatorTest.java +++ b/src/test/java/racingcar/validation/RacerValidatorTest.java @@ -6,7 +6,7 @@ import static org.assertj.core.api.Assertions.assertThat; -public class RacerValidatorTest { +class RacerValidatorTest { // TODO: 추후 검증기 모아 한 클래스 에서 테스트 @DisplayName("클래스 지원 테스트") @Test diff --git a/src/test/java/racingcar/validation/RoundValidatorTest.java b/src/test/java/racingcar/validation/RoundValidatorTest.java new file mode 100644 index 00000000000..b09062b6221 --- /dev/null +++ b/src/test/java/racingcar/validation/RoundValidatorTest.java @@ -0,0 +1,15 @@ +package racingcar.validation; + +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import racingcar.model.Round; + +import static org.assertj.core.api.Assertions.assertThat; +class RoundValidatorTest { + @DisplayName("클래스 지원 테스트") + @Test + void checkSupport() { + Validator validator = new RoundValidator(); + assertThat(validator.support(Round.class)).isTrue(); + } +} From f752a6ebe73ac0fbeb008108638364fcb3f80542 Mon Sep 17 00:00:00 2001 From: JongHyunJung Date: Tue, 28 Nov 2023 19:54:37 +0900 Subject: [PATCH 17/44] =?UTF-8?q?refactor:=20View=20=EC=97=90=EC=84=9C=20I?= =?UTF-8?q?nterface=20=EB=8F=84=EC=9E=85?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/racingcar/Application.java | 6 +-- .../controller/RacingCarController.java | 8 ++-- src/main/java/racingcar/view/InputView.java | 35 ++++++++------- .../java/racingcar/view/InputViewImpl.java | 23 ++++++++++ src/main/java/racingcar/view/OutputView.java | 43 ++++++++++--------- .../java/racingcar/view/OutputViewImpl.java | 19 ++++++++ 6 files changed, 90 insertions(+), 44 deletions(-) create mode 100644 src/main/java/racingcar/view/InputViewImpl.java create mode 100644 src/main/java/racingcar/view/OutputViewImpl.java diff --git a/src/main/java/racingcar/Application.java b/src/main/java/racingcar/Application.java index 80c29a4c12d..6e82610187d 100644 --- a/src/main/java/racingcar/Application.java +++ b/src/main/java/racingcar/Application.java @@ -1,12 +1,12 @@ package racingcar; import racingcar.controller.RacingCarController; -import racingcar.view.InputView; -import racingcar.view.OutputView; +import racingcar.view.InputViewImpl; +import racingcar.view.OutputViewImpl; public class Application { public static void main(String[] args) { - RacingCarController racingCarController = new RacingCarController(new InputView(), new OutputView()); + RacingCarController racingCarController = new RacingCarController(new InputViewImpl(), new OutputViewImpl()); racingCarController.run(); } } diff --git a/src/main/java/racingcar/controller/RacingCarController.java b/src/main/java/racingcar/controller/RacingCarController.java index 370d184b62c..714e98c028d 100644 --- a/src/main/java/racingcar/controller/RacingCarController.java +++ b/src/main/java/racingcar/controller/RacingCarController.java @@ -18,9 +18,9 @@ public void run(){ // String cars = inputView.readRaceCarNames(); // String resultCars = cars.replaceAll(" ", ""); // List names = List.of(resultCars.split(",")); - Racer racer = new Racer(inputView.readRaceCarNames()); + Racer racer = new Racer(inputView.readCars()); // int round = Integer.parseInt(inputView.readRaceRound()); - Round round = new Round(inputView.readRaceRound()); + Round round = new Round(inputView.readRound()); // 각각의 racer 초기화 // Map position = new LinkedHashMap<>(); @@ -32,7 +32,7 @@ public void run(){ // 라운드 별 각각의 레이서 결과 출력 while(round.isContinue()){ racer.play(); - outputView.printResult(racer); + outputView.printResult(racer.toString()); } // for (int i=0 ; i < round ; i++){ // racer.play(); @@ -42,7 +42,7 @@ public void run(){ // System.out.println(); // } - outputView.printWinner(racer.getWinner()); + outputView.printFinalWinner(racer.getWinner()); } // private void play(Map position) { diff --git a/src/main/java/racingcar/view/InputView.java b/src/main/java/racingcar/view/InputView.java index e8ca39a6d84..10a92cdb315 100644 --- a/src/main/java/racingcar/view/InputView.java +++ b/src/main/java/racingcar/view/InputView.java @@ -1,21 +1,24 @@ package racingcar.view; -import camp.nextstep.edu.missionutils.Console; -public class InputView { - private static final String ENTER_CAR_NAME = "경주할 자동차 이름을 입력 하세요.(이름은 쉼표(,) 기준 으로 구분)"; - private static final String ENTER_RACE_ROUND = "시도할 회수는 몇 회 인가요?"; +public interface InputView { + String readCars(); - public String readRaceCarNames() { - System.out.println(ENTER_CAR_NAME); - return readLine(); - } + String readRound(); - public String readRaceRound() { - System.out.println(ENTER_RACE_ROUND); - return readLine(); - } - - protected String readLine(){ - return Console.readLine(); - } +// private static final String ENTER_CAR_NAME = "경주할 자동차 이름을 입력 하세요.(이름은 쉼표(,) 기준 으로 구분)"; +// private static final String ENTER_RACE_ROUND = "시도할 회수는 몇 회 인가요?"; +// +// public String readRaceCarNames() { +// System.out.println(ENTER_CAR_NAME); +// return readLine(); +// } +// +// public String readRaceRound() { +// System.out.println(ENTER_RACE_ROUND); +// return readLine(); +// } +// +// protected String readLine(){ +// return Console.readLine(); +// } } diff --git a/src/main/java/racingcar/view/InputViewImpl.java b/src/main/java/racingcar/view/InputViewImpl.java new file mode 100644 index 00000000000..0eff9e19c9a --- /dev/null +++ b/src/main/java/racingcar/view/InputViewImpl.java @@ -0,0 +1,23 @@ +package racingcar.view; + +import camp.nextstep.edu.missionutils.Console; + +public class InputViewImpl implements InputView { + private static final String ENTER_CAR_NAME = "경주할 자동차 이름을 입력 하세요.(이름은 쉼표(,) 기준 으로 구분)"; + private static final String ENTER_RACE_ROUND = "시도할 회수는 몇 회 인가요?"; + @Override + public String readCars() { + System.out.println(ENTER_CAR_NAME); + return readLine(); + } + + @Override + public String readRound() { + System.out.println(ENTER_RACE_ROUND); + return readLine(); + } + + protected String readLine() { + return Console.readLine(); + } +} diff --git a/src/main/java/racingcar/view/OutputView.java b/src/main/java/racingcar/view/OutputView.java index c232cc09cf0..b0cb586753e 100644 --- a/src/main/java/racingcar/view/OutputView.java +++ b/src/main/java/racingcar/view/OutputView.java @@ -1,28 +1,29 @@ package racingcar.view; -import racingcar.model.Racer; +public interface OutputView { + void printExecution(); -import java.util.List; -import java.util.Map; + void printResult(String result); -public class OutputView { - private static final String ENTER_RACE_RESULT = "실행 결과"; - public void printExecution() { - System.out.println(ENTER_RACE_RESULT); - } + void printFinalWinner(String winner); - public void printResult(Racer racer){ -// for (String name : position.keySet()){ -// System.out.println(name + " : " + "-".repeat(position.get(name))); -// } - System.out.println(racer.toString()); - } - - public void printWinner(String winner){ - System.out.println("최종 우승자 : " + winner); - } - -// private String formatted(List winner){ -// return String.join(", ", winner); +// private static final String ENTER_RACE_RESULT = "실행 결과"; +// public void printExecution() { +// System.out.println(ENTER_RACE_RESULT); +// } +// +// public void printResult(Racer racer){ +//// for (String name : position.keySet()){ +//// System.out.println(name + " : " + "-".repeat(position.get(name))); +//// } +// System.out.println(racer.toString()); +// } +// +// public void printWinner(String winner){ +// System.out.println("최종 우승자 : " + winner); // } +// +//// private String formatted(List winner){ +//// return String.join(", ", winner); +//// } } diff --git a/src/main/java/racingcar/view/OutputViewImpl.java b/src/main/java/racingcar/view/OutputViewImpl.java new file mode 100644 index 00000000000..212ac0572f9 --- /dev/null +++ b/src/main/java/racingcar/view/OutputViewImpl.java @@ -0,0 +1,19 @@ +package racingcar.view; + +public class OutputViewImpl implements OutputView { + private static final String ENTER_RACE_RESULT = "실행 결과"; + @Override + public void printExecution() { + System.out.println(ENTER_RACE_RESULT); + } + + @Override + public void printResult(String result) { + System.out.println(result); + } + + @Override + public void printFinalWinner(String winner) { + System.out.println("최종 우승자 : " + winner); + } +} From 148a058a8db26ed51bf738457c5a90c62845b408 Mon Sep 17 00:00:00 2001 From: JongHyunJung Date: Tue, 28 Nov 2023 19:59:27 +0900 Subject: [PATCH 18/44] =?UTF-8?q?refactor:=20RacingCar=20Application=20?= =?UTF-8?q?=EC=83=9D=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/racingcar/Application.java | 7 +++++-- .../application/RacingCarApplication.java | 18 ++++++++++++++++++ 2 files changed, 23 insertions(+), 2 deletions(-) create mode 100644 src/main/java/racingcar/application/RacingCarApplication.java diff --git a/src/main/java/racingcar/Application.java b/src/main/java/racingcar/Application.java index 6e82610187d..46c6bb6e353 100644 --- a/src/main/java/racingcar/Application.java +++ b/src/main/java/racingcar/Application.java @@ -1,12 +1,15 @@ package racingcar; +import racingcar.application.RacingCarApplication; import racingcar.controller.RacingCarController; import racingcar.view.InputViewImpl; import racingcar.view.OutputViewImpl; public class Application { public static void main(String[] args) { - RacingCarController racingCarController = new RacingCarController(new InputViewImpl(), new OutputViewImpl()); - racingCarController.run(); +// RacingCarController racingCarController = new RacingCarController(new InputViewImpl(), new OutputViewImpl()); +// racingCarController.run(); + RacingCarApplication racingCarApplication = new RacingCarApplication();= + racingCarApplication.run(); } } diff --git a/src/main/java/racingcar/application/RacingCarApplication.java b/src/main/java/racingcar/application/RacingCarApplication.java new file mode 100644 index 00000000000..8052a9435f0 --- /dev/null +++ b/src/main/java/racingcar/application/RacingCarApplication.java @@ -0,0 +1,18 @@ +package racingcar.application; + +import racingcar.controller.RacingCarController; +import racingcar.view.InputView; +import racingcar.view.OutputView; +import racingcar.view.InputViewImpl; +import racingcar.view.OutputViewImpl; + +public class RacingCarApplication { + public void run() { + InputView inputView = new InputViewImpl(); + OutputView outputView = new OutputViewImpl(); + + RacingCarController racingCarController = new RacingCarController(inputView, outputView); + racingCarController.run(); + } +} + From de5d24c9e0a49d5e8a0abfb5248c5cdc6f212960 Mon Sep 17 00:00:00 2001 From: JongHyunJung Date: Tue, 28 Nov 2023 20:03:42 +0900 Subject: [PATCH 19/44] =?UTF-8?q?refactor:=20hasRound()=20=EB=A9=94?= =?UTF-8?q?=EC=84=9C=EB=93=9C=20=EB=AA=85=20=EB=B3=80=EA=B2=BD=20=EB=B0=8F?= =?UTF-8?q?=20=EB=A9=94=EC=84=9C=EB=93=9C=20=EB=B6=84=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/racingcar/Application.java | 4 +++- .../controller/RacingCarController.java | 2 +- src/main/java/racingcar/model/Round.java | 20 +++++++++++++------ 3 files changed, 18 insertions(+), 8 deletions(-) diff --git a/src/main/java/racingcar/Application.java b/src/main/java/racingcar/Application.java index 46c6bb6e353..754208489ee 100644 --- a/src/main/java/racingcar/Application.java +++ b/src/main/java/racingcar/Application.java @@ -9,7 +9,9 @@ public class Application { public static void main(String[] args) { // RacingCarController racingCarController = new RacingCarController(new InputViewImpl(), new OutputViewImpl()); // racingCarController.run(); - RacingCarApplication racingCarApplication = new RacingCarApplication();= + + RacingCarApplication racingCarApplication = new RacingCarApplication(); + racingCarApplication.run(); } } diff --git a/src/main/java/racingcar/controller/RacingCarController.java b/src/main/java/racingcar/controller/RacingCarController.java index 714e98c028d..2b49d2117c4 100644 --- a/src/main/java/racingcar/controller/RacingCarController.java +++ b/src/main/java/racingcar/controller/RacingCarController.java @@ -30,7 +30,7 @@ public void run(){ outputView.printExecution(); // 라운드 별 각각의 레이서 결과 출력 - while(round.isContinue()){ + while(round.hasRound()){ racer.play(); outputView.printResult(racer.toString()); } diff --git a/src/main/java/racingcar/model/Round.java b/src/main/java/racingcar/model/Round.java index 12eb0f2c23f..8377e377636 100644 --- a/src/main/java/racingcar/model/Round.java +++ b/src/main/java/racingcar/model/Round.java @@ -15,12 +15,20 @@ public Round(String round){ } // TODO: 진행 중인지 확인 하는 것 뿐 아니라 감소도 함 - public Boolean isContinue(){ - if (round > 0){ - round --; - return true; - } - return false; +// public Boolean isContinue(){ +// if (round > 0){ +// round --; +// return true; +// } +// return false; +// } + public Boolean hasRound(){ + turn(); + return round >= 0; + } + + public void turn() { + round--; } private void validate(String value){ From 0503e6c4fd325d2bf7888c9a3dbfaef3efac392e Mon Sep 17 00:00:00 2001 From: JongHyunJung Date: Tue, 28 Nov 2023 20:05:08 +0900 Subject: [PATCH 20/44] =?UTF-8?q?doc:=20=EB=A6=AC=ED=8C=A9=ED=86=A0?= =?UTF-8?q?=EB=A7=81=20=EB=AA=A9=EB=A1=9D=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/README.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/docs/README.md b/docs/README.md index 3e6b3089060..dab399d7a71 100644 --- a/docs/README.md +++ b/docs/README.md @@ -33,4 +33,5 @@ ## 🔨 리팩토링 목록 * [x] 1급 Collection 적용 * [ ] 상수 사용 -* [ ] interface 활용 (메세지 던지기) \ No newline at end of file +* [ ] interface 활용 (메세지 던지기) +* [ ] Integer 대신 Long 사용 고려 \ No newline at end of file From 3605cb834525aec03f42981a53e5cd7b67c81803 Mon Sep 17 00:00:00 2001 From: JongHyunJung Date: Tue, 28 Nov 2023 20:32:05 +0900 Subject: [PATCH 21/44] =?UTF-8?q?feat:=20=EC=97=AC=EB=9F=AC=20=EB=B0=A9?= =?UTF-8?q?=EB=B2=95=EC=9C=BC=EB=A1=9C=20=EC=A0=95=EB=A0=AC=20=EC=88=98?= =?UTF-8?q?=ED=96=89=ED=95=A0=20=EC=88=98=20=EC=9E=88=EB=8F=84=EB=A1=9D=20?= =?UTF-8?q?=EA=B5=AC=EC=A1=B0=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../controller/RacingCarController.java | 2 +- src/main/java/racingcar/model/Racer.java | 32 +++++++++++++++---- .../java/racingcar/model/{ => car}/Car.java | 26 +++++++++------ .../racingcar/model/car/OrderByPosition.java | 8 +++++ .../racingcar/model/car/OrderStrategy.java | 8 +++++ .../racingcar/validation/CarValidator.java | 2 +- src/test/java/racingcar/model/CarTest.java | 1 + .../validation/CarValidatorTest.java | 2 +- 8 files changed, 62 insertions(+), 19 deletions(-) rename src/main/java/racingcar/model/{ => car}/Car.java (70%) create mode 100644 src/main/java/racingcar/model/car/OrderByPosition.java create mode 100644 src/main/java/racingcar/model/car/OrderStrategy.java diff --git a/src/main/java/racingcar/controller/RacingCarController.java b/src/main/java/racingcar/controller/RacingCarController.java index 2b49d2117c4..411b47e8c3a 100644 --- a/src/main/java/racingcar/controller/RacingCarController.java +++ b/src/main/java/racingcar/controller/RacingCarController.java @@ -42,7 +42,7 @@ public void run(){ // System.out.println(); // } - outputView.printFinalWinner(racer.getWinner()); + outputView.printFinalWinner(racer.winnerToString()); } // private void play(Map position) { diff --git a/src/main/java/racingcar/model/Racer.java b/src/main/java/racingcar/model/Racer.java index 705ef554050..519a1e4fdcf 100644 --- a/src/main/java/racingcar/model/Racer.java +++ b/src/main/java/racingcar/model/Racer.java @@ -1,11 +1,11 @@ package racingcar.model; +import racingcar.model.car.Car; import racingcar.validation.RacerValidator; import racingcar.validation.Validator; import java.util.Arrays; import java.util.List; -import java.util.stream.Collectors; public class Racer { public static final String SEPERATOR = ","; @@ -27,13 +27,33 @@ private void validate(String value){ validator.validate(value); } - public String getWinner() { - Car winner = racer.stream().max(Car::compareTo).orElseThrow(); +// public String getWinner() { +// Car winner = racer.stream().max(Car::compareTo).orElseThrow(); +// +// return racer.stream() +// .filter(winner::equals) +// .map(Car::getName) +// .collect(Collectors.joining(SEPERATOR)); +// } + + public List getWinner() { + Car first = racer.stream() + .max(Car::compareTo) + .orElseThrow(IllegalAccessError::new); return racer.stream() - .filter(winner::equals) - .map(Car::getName) - .collect(Collectors.joining(SEPERATOR)); + .filter(car -> car.equals(first)) + .toList(); + } + + public String winnerToString() { + List winner = getWinner(); + StringBuilder stringBuilder = new StringBuilder(); + for (Car car : winner){ + stringBuilder.append(car.getName()).append(","); + } + stringBuilder.deleteCharAt(stringBuilder.length() - 1); + return stringBuilder.toString(); } @Override diff --git a/src/main/java/racingcar/model/Car.java b/src/main/java/racingcar/model/car/Car.java similarity index 70% rename from src/main/java/racingcar/model/Car.java rename to src/main/java/racingcar/model/car/Car.java index 6bc8bc65989..e2d03e34736 100644 --- a/src/main/java/racingcar/model/Car.java +++ b/src/main/java/racingcar/model/car/Car.java @@ -1,18 +1,24 @@ -package racingcar.model; +package racingcar.model.car; import racingcar.service.ShiftGear; import racingcar.validation.CarValidator; import racingcar.validation.Validator; -public class Car implements Comparable { +import java.util.Comparator; + +// TODO : 자동차 경주에 말이 들어 온다면? +public class Car { private static final String MARK = "-"; - private final String name; - private Integer currentPosition; + // TODO : 어떻게 선언 할까 + private final Comparator comparator = new OrderByPosition(); + + protected String name; + protected Integer currentPosition; public Car(String name){ - validateName(name); - this.name = name; - this.currentPosition = 0; + validate(name); +// this.name = name; +// this.currentPosition = 0; } public void move() { @@ -21,7 +27,7 @@ public void move() { } } - private void validateName(String value){ + private void validate(String value){ Validator carValidator = new CarValidator(); if(carValidator.support(Car.class)) { carValidator.validate(value); @@ -49,9 +55,9 @@ public boolean equals(Object obj){ return this.currentPosition.equals(car.currentPosition); } - @Override public int compareTo(Car car) { - return this.currentPosition - car.currentPosition; + return comparator.compare(this, car); +// return this.currentPosition - car.currentPosition; } // private void validateName(String name){ diff --git a/src/main/java/racingcar/model/car/OrderByPosition.java b/src/main/java/racingcar/model/car/OrderByPosition.java new file mode 100644 index 00000000000..bb88d4398c2 --- /dev/null +++ b/src/main/java/racingcar/model/car/OrderByPosition.java @@ -0,0 +1,8 @@ +package racingcar.model.car; + +public class OrderByPosition implements OrderStrategy { + @Override + public int compare(Car o1, Car o2) { + return o1.currentPosition - o2.currentPosition; + } +} diff --git a/src/main/java/racingcar/model/car/OrderStrategy.java b/src/main/java/racingcar/model/car/OrderStrategy.java new file mode 100644 index 00000000000..71f7750cef1 --- /dev/null +++ b/src/main/java/racingcar/model/car/OrderStrategy.java @@ -0,0 +1,8 @@ +package racingcar.model.car; + +import java.util.Comparator; + +public interface OrderStrategy extends Comparator { + @Override + int compare(Car o1, Car o2); +} diff --git a/src/main/java/racingcar/validation/CarValidator.java b/src/main/java/racingcar/validation/CarValidator.java index 5e883ab99d6..f3e9c2b650d 100644 --- a/src/main/java/racingcar/validation/CarValidator.java +++ b/src/main/java/racingcar/validation/CarValidator.java @@ -1,6 +1,6 @@ package racingcar.validation; -import racingcar.model.Car; +import racingcar.model.car.Car; import static racingcar.type.PlayType.MAX_LENGTH; import static racingcar.type.PlayType.MIN_LENGTH; diff --git a/src/test/java/racingcar/model/CarTest.java b/src/test/java/racingcar/model/CarTest.java index 6f320ccad96..41f639741a0 100644 --- a/src/test/java/racingcar/model/CarTest.java +++ b/src/test/java/racingcar/model/CarTest.java @@ -3,6 +3,7 @@ import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.ValueSource; +import racingcar.model.car.Car; import static org.assertj.core.api.Assertions.assertThatThrownBy; diff --git a/src/test/java/racingcar/validation/CarValidatorTest.java b/src/test/java/racingcar/validation/CarValidatorTest.java index ed2cc52a0fc..a976c2be3fb 100644 --- a/src/test/java/racingcar/validation/CarValidatorTest.java +++ b/src/test/java/racingcar/validation/CarValidatorTest.java @@ -2,7 +2,7 @@ import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; -import racingcar.model.Car; +import racingcar.model.car.Car; import static org.assertj.core.api.Assertions.assertThat; From f66dfca6f808780bb202f7eb06e514777377dc53 Mon Sep 17 00:00:00 2001 From: JongHyunJung Date: Tue, 28 Nov 2023 20:33:52 +0900 Subject: [PATCH 22/44] =?UTF-8?q?docs:=20=EA=B3=A0=EB=AF=BC=20=EC=A3=BC?= =?UTF-8?q?=EC=A0=9C=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/README.md | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/docs/README.md b/docs/README.md index dab399d7a71..a0ac17b548a 100644 --- a/docs/README.md +++ b/docs/README.md @@ -34,4 +34,13 @@ * [x] 1급 Collection 적용 * [ ] 상수 사용 * [ ] interface 활용 (메세지 던지기) -* [ ] Integer 대신 Long 사용 고려 \ No newline at end of file +* [ ] Integer 대신 Long 사용 고려 + +## 고민해볼 주제 + +* [ ] 자동차 이름에 중복 포함된 경우 +* [ ] 마지막 ,로 끝나는 경우 +* [ ] 사용자 이름에 공백이 들어가도 되는 걸까 +* [ ] 각 차수별 실행 결과 출력의 순서 + * 사용자 입력 순 + * 사전 정렬 순 \ No newline at end of file From d41f3beeb08605c9cbdb7014801ea4928bfda7f1 Mon Sep 17 00:00:00 2001 From: JongHyunJung Date: Tue, 28 Nov 2023 20:36:41 +0900 Subject: [PATCH 23/44] =?UTF-8?q?fix:=200=EB=B2=88=20=EC=8B=9C=EB=8F=84?= =?UTF-8?q?=EB=8F=84=20=EA=B0=80=EB=8A=A5=ED=95=98=EB=8F=84=EB=A1=9D=20?= =?UTF-8?q?=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/racingcar/validation/RoundValidator.java | 2 +- src/test/java/racingcar/model/RoundTest.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/racingcar/validation/RoundValidator.java b/src/main/java/racingcar/validation/RoundValidator.java index d1367f3ce63..0b1a11970f8 100644 --- a/src/main/java/racingcar/validation/RoundValidator.java +++ b/src/main/java/racingcar/validation/RoundValidator.java @@ -25,7 +25,7 @@ private void validateType(String value){ } private void validateRange(String value){ - if (0 >= Integer.parseInt(value)) { + if (0 > Integer.parseInt(value)) { throw new IllegalArgumentException(); } } diff --git a/src/test/java/racingcar/model/RoundTest.java b/src/test/java/racingcar/model/RoundTest.java index 563f117c597..76c2c9299bb 100644 --- a/src/test/java/racingcar/model/RoundTest.java +++ b/src/test/java/racingcar/model/RoundTest.java @@ -10,7 +10,7 @@ class RoundTest { @DisplayName("잘못된 횟수 입력 테스트") @ParameterizedTest(name = "{displayName}: {0}") - @ValueSource(strings = {"0", "-123", "akd", "", "-", "12a", " 1"}) + @ValueSource(strings = {"-123", "akd", "", "-", "12a", " 1"}) @NullSource void checkInvalidRound(String value){ assertThatThrownBy(() -> From e72c821e242a04e5157fc78895626e71c0dbb4e8 Mon Sep 17 00:00:00 2001 From: JongHyunJung Date: Tue, 28 Nov 2023 20:38:12 +0900 Subject: [PATCH 24/44] =?UTF-8?q?remove:=20=EC=9D=B4=EC=A0=84=20=EC=8A=B9?= =?UTF-8?q?=EC=9E=90=20=ED=99=95=EC=9D=B8=20=ED=81=B4=EB=9E=98=EC=8A=A4=20?= =?UTF-8?q?=EC=82=AD=EC=A0=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/racingcar/service/JudgeWinner.java | 40 +++++++++---------- 1 file changed, 20 insertions(+), 20 deletions(-) diff --git a/src/main/java/racingcar/service/JudgeWinner.java b/src/main/java/racingcar/service/JudgeWinner.java index 046c95cb6e0..2b8c0e1a55e 100644 --- a/src/main/java/racingcar/service/JudgeWinner.java +++ b/src/main/java/racingcar/service/JudgeWinner.java @@ -4,23 +4,23 @@ import java.util.Map; import java.util.stream.Collectors; -public class JudgeWinner { - private JudgeWinner() {} - - public static List chooseWinner(Map position){ - int winnerPosition = calculatePosition(position); - return position.keySet().stream() - .filter(name -> isWinner(position.get(name), winnerPosition)) - .collect(Collectors.toList()); - } - - private static Integer calculatePosition(Map position){ - return position.values().stream() - .max(Integer::compare) - .orElse(0); - } - - private static boolean isWinner(int racerPosition, int winnerPosition){ - return racerPosition == winnerPosition; - } -} +//public class JudgeWinner { +// private JudgeWinner() {} +// +// public static List chooseWinner(Map position){ +// int winnerPosition = calculatePosition(position); +// return position.keySet().stream() +// .filter(name -> isWinner(position.get(name), winnerPosition)) +// .collect(Collectors.toList()); +// } +// +// private static Integer calculatePosition(Map position){ +// return position.values().stream() +// .max(Integer::compare) +// .orElse(0); +// } +// +// private static boolean isWinner(int racerPosition, int winnerPosition){ +// return racerPosition == winnerPosition; +// } +//} From f2367ff064b28557cc1c777dcf2015b921c088e5 Mon Sep 17 00:00:00 2001 From: JongHyunJung Date: Tue, 28 Nov 2023 20:41:10 +0900 Subject: [PATCH 25/44] =?UTF-8?q?refactor:=20=EC=B6=9C=EB=A0=A5=20?= =?UTF-8?q?=EA=B0=92=20=ED=8F=AC=EC=9E=A5=20=EC=8B=9C=20stream=20API=20?= =?UTF-8?q?=EC=82=AC=EC=9A=A9=ED=95=98=EA=B8=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/racingcar/model/Racer.java | 22 ++++++++++++++-------- 1 file changed, 14 insertions(+), 8 deletions(-) diff --git a/src/main/java/racingcar/model/Racer.java b/src/main/java/racingcar/model/Racer.java index 519a1e4fdcf..aeb004da86f 100644 --- a/src/main/java/racingcar/model/Racer.java +++ b/src/main/java/racingcar/model/Racer.java @@ -17,7 +17,6 @@ public Racer(String name) { .toList(); } - // TODO: 메서드 위치 고민 해보기 public void play(){ racer.forEach(Car::move); } @@ -47,13 +46,20 @@ public List getWinner() { } public String winnerToString() { - List winner = getWinner(); - StringBuilder stringBuilder = new StringBuilder(); - for (Car car : winner){ - stringBuilder.append(car.getName()).append(","); - } - stringBuilder.deleteCharAt(stringBuilder.length() - 1); - return stringBuilder.toString(); + List winner = getWinner() + .stream() + .map(Car::getName) + .toList(); + + return String.join(SEPERATOR, winner); + +// List winner = getWinner(); +// StringBuilder stringBuilder = new StringBuilder(); +// for (Car car : winner){ +// stringBuilder.append(car.getName()).append(","); +// } +// stringBuilder.deleteCharAt(stringBuilder.length() - 1); +// return stringBuilder.toString(); } @Override From 84ed92b2baf43743cdb138e449b6a52ac2c204f7 Mon Sep 17 00:00:00 2001 From: JongHyunJung Date: Tue, 28 Nov 2023 21:09:59 +0900 Subject: [PATCH 26/44] =?UTF-8?q?refactor:=20=EA=B2=80=EC=A6=9D=EA=B8=B0?= =?UTF-8?q?=20Factory=20=EA=B5=AC=ED=98=84=20=ED=9B=84=20=ED=95=B4?= =?UTF-8?q?=EB=8B=B9=20=ED=8C=A9=ED=86=A0=EB=A6=AC=EC=97=90=EC=84=9C=20get?= =?UTF-8?q?=20=EA=B2=80=EC=A6=9D=EA=B8=B0=20=ED=98=95=ED=83=9C=EB=A1=9C=20?= =?UTF-8?q?=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/racingcar/model/Racer.java | 6 +++- src/main/java/racingcar/model/Round.java | 6 +++- src/main/java/racingcar/model/car/Car.java | 13 ++++--- .../validation/ValidatorFactory.java | 36 +++++++++++++++++++ .../validation/ValidatorFactoryTest.java | 33 +++++++++++++++++ 5 files changed, 88 insertions(+), 6 deletions(-) create mode 100644 src/main/java/racingcar/validation/ValidatorFactory.java create mode 100644 src/test/java/racingcar/validation/ValidatorFactoryTest.java diff --git a/src/main/java/racingcar/model/Racer.java b/src/main/java/racingcar/model/Racer.java index aeb004da86f..c27a9d06a0e 100644 --- a/src/main/java/racingcar/model/Racer.java +++ b/src/main/java/racingcar/model/Racer.java @@ -3,6 +3,7 @@ import racingcar.model.car.Car; import racingcar.validation.RacerValidator; import racingcar.validation.Validator; +import racingcar.validation.ValidatorFactory; import java.util.Arrays; import java.util.List; @@ -22,8 +23,11 @@ public void play(){ } private void validate(String value){ - Validator validator = new RacerValidator(); + ValidatorFactory validatorFactory = ValidatorFactory.buildDefaultValidatorFactory(); + Validator validator = validatorFactory.getValidator(this.getClass()); validator.validate(value); +// Validator validator = new RacerValidator(); +// validator.validate(value); } // public String getWinner() { diff --git a/src/main/java/racingcar/model/Round.java b/src/main/java/racingcar/model/Round.java index 8377e377636..256336f682f 100644 --- a/src/main/java/racingcar/model/Round.java +++ b/src/main/java/racingcar/model/Round.java @@ -2,6 +2,7 @@ import racingcar.validation.RoundValidator; import racingcar.validation.Validator; +import racingcar.validation.ValidatorFactory; import static racingcar.type.PlayType.MAX_NUM; import static racingcar.type.PlayType.MIN_NUM; @@ -32,8 +33,11 @@ public void turn() { } private void validate(String value){ - Validator validator = new RoundValidator(); + ValidatorFactory validatorFactory = ValidatorFactory.buildDefaultValidatorFactory(); + Validator validator = validatorFactory.getValidator(this.getClass()); validator.validate(value); +// Validator validator = new RoundValidator(); +// validator.validate(value); // validateType(value); // validateRange(value); } diff --git a/src/main/java/racingcar/model/car/Car.java b/src/main/java/racingcar/model/car/Car.java index e2d03e34736..41ed2518d76 100644 --- a/src/main/java/racingcar/model/car/Car.java +++ b/src/main/java/racingcar/model/car/Car.java @@ -3,6 +3,7 @@ import racingcar.service.ShiftGear; import racingcar.validation.CarValidator; import racingcar.validation.Validator; +import racingcar.validation.ValidatorFactory; import java.util.Comparator; @@ -28,10 +29,14 @@ public void move() { } private void validate(String value){ - Validator carValidator = new CarValidator(); - if(carValidator.support(Car.class)) { - carValidator.validate(value); - } + // TODO : 다른 방식으로 구현체 가져오기 + ValidatorFactory validatorFactory = ValidatorFactory.buildDefaultValidatorFactory(); + Validator validator = validatorFactory.getValidator(this.getClass()); + validator.validate(value); +// Validator carValidator = new CarValidator(); +// if(carValidator.support(Car.class)) { +// carValidator.validate(value); +// } } public String getName() { diff --git a/src/main/java/racingcar/validation/ValidatorFactory.java b/src/main/java/racingcar/validation/ValidatorFactory.java new file mode 100644 index 00000000000..ad07a2c0124 --- /dev/null +++ b/src/main/java/racingcar/validation/ValidatorFactory.java @@ -0,0 +1,36 @@ +package racingcar.validation; + +import java.util.HashSet; +import java.util.Set; + +public class ValidatorFactory { + private static ValidatorFactory validatorFactory; + private final Set validators = new HashSet<>(); + private ValidatorFactory() {} + + public static ValidatorFactory buildDefaultValidatorFactory() { + if (validatorFactory != null){ + return validatorFactory; + } + + validatorFactory = new ValidatorFactory(); + validatorFactory.registerValidator(new CarValidator()); + validatorFactory.registerValidator(new RoundValidator()); + validatorFactory.registerValidator(new RacerValidator()); + + return validatorFactory; + } + + private void registerValidator(Validator validator) { + validators.add(validator); + } + + public Validator getValidator(Class clazz) { + for (Validator validator : validators){ + if (validator.support(clazz)){ + return validator; + } + } + throw new IllegalArgumentException(); + } +} diff --git a/src/test/java/racingcar/validation/ValidatorFactoryTest.java b/src/test/java/racingcar/validation/ValidatorFactoryTest.java new file mode 100644 index 00000000000..0a5e60893b2 --- /dev/null +++ b/src/test/java/racingcar/validation/ValidatorFactoryTest.java @@ -0,0 +1,33 @@ +package racingcar.validation; + +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.Arguments; +import org.junit.jupiter.params.provider.MethodSource; +import racingcar.model.Racer; +import racingcar.model.Round; +import racingcar.model.car.Car; + +import java.util.stream.Stream; + +import static org.assertj.core.api.Assertions.assertThat; + +public class ValidatorFactoryTest { + + @DisplayName("클래스에 맞는 검증기 가져오는지 테스트") + @ParameterizedTest(name = "{index} {0}, {1}") + @MethodSource("checkValidatorParametersProvider") + void checkValidatorFactory(Class clazz, Validator validator){ + ValidatorFactory validatorFactory = ValidatorFactory.buildDefaultValidatorFactory(); + + assertThat(validatorFactory.getValidator(clazz)).isInstanceOf(validator.getClass()); + } + + static Stream checkValidatorParametersProvider() { + return Stream.of( + Arguments.arguments(Car.class, new CarValidator()), + Arguments.arguments(Racer.class, new RacerValidator()), + Arguments.arguments(Round.class, new RoundValidator()) + ); + } +} From 1cd21514abd1ab564cfab12b8caff8705afaf035 Mon Sep 17 00:00:00 2001 From: JongHyunJung Date: Tue, 28 Nov 2023 21:15:46 +0900 Subject: [PATCH 27/44] =?UTF-8?q?docs:=20=EC=98=88=EC=99=B8=20=EC=82=AC?= =?UTF-8?q?=ED=95=AD=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/README.md b/docs/README.md index a0ac17b548a..1a88f4493f8 100644 --- a/docs/README.md +++ b/docs/README.md @@ -22,6 +22,8 @@ ## 예외 사항 * [x] 경주할 자동차 없는 경우 * [x] 경주할 자동차 이름이 1 이상 5 이하가 아닌 경우 +* [ ] 경주할 자동차 이름이 공백인 경우 +* [ ] 경주할 자동차 중 중복된 이름이 있는 경우 * [ ] 경주할 자동차 구분자 "," 가 아닌 경우 * [x] 시도할 횟수가 자연수 아닌 경우 @@ -38,9 +40,7 @@ ## 고민해볼 주제 -* [ ] 자동차 이름에 중복 포함된 경우 * [ ] 마지막 ,로 끝나는 경우 -* [ ] 사용자 이름에 공백이 들어가도 되는 걸까 * [ ] 각 차수별 실행 결과 출력의 순서 * 사용자 입력 순 * 사전 정렬 순 \ No newline at end of file From ceff32e79841733b01ba3189ecdfb038d953d42d Mon Sep 17 00:00:00 2001 From: JongHyunJung Date: Tue, 28 Nov 2023 21:16:18 +0900 Subject: [PATCH 28/44] =?UTF-8?q?style:=20=EC=B6=9C=EB=A0=A5=EC=8B=9C=20?= =?UTF-8?q?=EA=B3=B5=EB=B0=B1=20=EB=B0=8F=20=EA=B0=9C=ED=96=89=20=EC=B6=94?= =?UTF-8?q?=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/racingcar/model/Racer.java | 2 +- src/main/java/racingcar/view/OutputViewImpl.java | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/main/java/racingcar/model/Racer.java b/src/main/java/racingcar/model/Racer.java index c27a9d06a0e..aec90d03dc4 100644 --- a/src/main/java/racingcar/model/Racer.java +++ b/src/main/java/racingcar/model/Racer.java @@ -55,7 +55,7 @@ public String winnerToString() { .map(Car::getName) .toList(); - return String.join(SEPERATOR, winner); + return String.join(SEPERATOR + " ", winner); // List winner = getWinner(); // StringBuilder stringBuilder = new StringBuilder(); diff --git a/src/main/java/racingcar/view/OutputViewImpl.java b/src/main/java/racingcar/view/OutputViewImpl.java index 212ac0572f9..551c7375f72 100644 --- a/src/main/java/racingcar/view/OutputViewImpl.java +++ b/src/main/java/racingcar/view/OutputViewImpl.java @@ -1,7 +1,7 @@ package racingcar.view; public class OutputViewImpl implements OutputView { - private static final String ENTER_RACE_RESULT = "실행 결과"; + private static final String ENTER_RACE_RESULT = "\n실행 결과"; @Override public void printExecution() { System.out.println(ENTER_RACE_RESULT); @@ -14,6 +14,6 @@ public void printResult(String result) { @Override public void printFinalWinner(String winner) { - System.out.println("최종 우승자 : " + winner); + System.out.print("최종 우승자 : " + winner); } } From 5e75e49d21aa3281e692b74d70b87d10511fe3a0 Mon Sep 17 00:00:00 2001 From: JongHyunJung Date: Tue, 28 Nov 2023 21:20:22 +0900 Subject: [PATCH 29/44] =?UTF-8?q?feat:=20=EA=B2=BD=EC=A3=BC=ED=95=A0=20?= =?UTF-8?q?=EC=9E=90=EB=8F=99=EC=B0=A8=20=EC=9D=B4=EB=A6=84=20=EA=B3=B5?= =?UTF-8?q?=EB=B0=B1=EC=9D=BC=20=EA=B2=BD=EC=9A=B0=20=EC=98=88=EC=99=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/README.md | 2 +- src/main/java/racingcar/validation/CarValidator.java | 7 +++++++ src/test/java/racingcar/model/CarTest.java | 2 +- 3 files changed, 9 insertions(+), 2 deletions(-) diff --git a/docs/README.md b/docs/README.md index 1a88f4493f8..97b6a0fd032 100644 --- a/docs/README.md +++ b/docs/README.md @@ -22,7 +22,7 @@ ## 예외 사항 * [x] 경주할 자동차 없는 경우 * [x] 경주할 자동차 이름이 1 이상 5 이하가 아닌 경우 -* [ ] 경주할 자동차 이름이 공백인 경우 +* [x] 경주할 자동차 이름이 공백인 경우 * [ ] 경주할 자동차 중 중복된 이름이 있는 경우 * [ ] 경주할 자동차 구분자 "," 가 아닌 경우 * [x] 시도할 횟수가 자연수 아닌 경우 diff --git a/src/main/java/racingcar/validation/CarValidator.java b/src/main/java/racingcar/validation/CarValidator.java index f3e9c2b650d..34af3854d64 100644 --- a/src/main/java/racingcar/validation/CarValidator.java +++ b/src/main/java/racingcar/validation/CarValidator.java @@ -14,6 +14,7 @@ public boolean support(Class clazz) { @Override public void validate(Object target) { validateLength((String) target); + validateSpace((String) target); } private void validateLength(String value){ @@ -21,4 +22,10 @@ private void validateLength(String value){ throw new IllegalArgumentException(); } } + + private void validateSpace(String value){ + if (value.trim().equals("")){ + throw new IllegalArgumentException(); + } + } } diff --git a/src/test/java/racingcar/model/CarTest.java b/src/test/java/racingcar/model/CarTest.java index 41f639741a0..1ee11a871dd 100644 --- a/src/test/java/racingcar/model/CarTest.java +++ b/src/test/java/racingcar/model/CarTest.java @@ -10,7 +10,7 @@ class CarTest { @DisplayName("자동차 이름의 길이가 잘못된 경우 예외 발생") @ParameterizedTest(name = "{displayName} value = {0}") - @ValueSource(strings = {"soul", "bb", "안 녕"}) + @ValueSource(strings = {"myCarIsKia", "myName", " "}) void checkValidateLength(String name){ assertThatThrownBy(() -> new Car(name)) .isInstanceOf(IllegalArgumentException.class); From 483f5fa25857d87d5fd8241286b23fc5a9812d8d Mon Sep 17 00:00:00 2001 From: JongHyunJung Date: Tue, 28 Nov 2023 21:35:51 +0900 Subject: [PATCH 30/44] =?UTF-8?q?feat:=20=ED=9A=9F=EC=88=98=20=ED=83=80?= =?UTF-8?q?=EC=9E=85=20Integer=20=EB=8C=80=EC=8B=A0=20Long=20=EC=82=AC?= =?UTF-8?q?=EC=9A=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/README.md | 2 +- src/main/java/racingcar/model/Round.java | 5 +++-- src/main/java/racingcar/model/car/Car.java | 16 +++++++++++----- .../racingcar/model/car/OrderByPosition.java | 2 +- src/test/java/racingcar/model/RoundTest.java | 8 ++++++++ 5 files changed, 24 insertions(+), 9 deletions(-) diff --git a/docs/README.md b/docs/README.md index 97b6a0fd032..b24683e6bfe 100644 --- a/docs/README.md +++ b/docs/README.md @@ -36,7 +36,7 @@ * [x] 1급 Collection 적용 * [ ] 상수 사용 * [ ] interface 활용 (메세지 던지기) -* [ ] Integer 대신 Long 사용 고려 +* [x] Integer 대신 Long 사용 고려 ## 고민해볼 주제 diff --git a/src/main/java/racingcar/model/Round.java b/src/main/java/racingcar/model/Round.java index 256336f682f..370541f026b 100644 --- a/src/main/java/racingcar/model/Round.java +++ b/src/main/java/racingcar/model/Round.java @@ -8,11 +8,12 @@ import static racingcar.type.PlayType.MIN_NUM; public class Round { - private Integer round; + private Long round; +// private Integer round; public Round(String round){ validate(round); - this.round = Integer.parseInt(round); + this.round = Long.valueOf(round); } // TODO: 진행 중인지 확인 하는 것 뿐 아니라 감소도 함 diff --git a/src/main/java/racingcar/model/car/Car.java b/src/main/java/racingcar/model/car/Car.java index 41ed2518d76..779010bc401 100644 --- a/src/main/java/racingcar/model/car/Car.java +++ b/src/main/java/racingcar/model/car/Car.java @@ -13,13 +13,13 @@ public class Car { // TODO : 어떻게 선언 할까 private final Comparator comparator = new OrderByPosition(); - protected String name; - protected Integer currentPosition; + protected final String name; + protected Long currentPosition; public Car(String name){ validate(name); -// this.name = name; -// this.currentPosition = 0; + this.name = name; + this.currentPosition = 0L; } public void move() { @@ -45,7 +45,13 @@ public String getName() { @Override public String toString(){ - return this.name + " : " + MARK.repeat(this.currentPosition); + StringBuilder stringBuilder = new StringBuilder(); + stringBuilder.append(this.name).append(" : "); + for (long i=0 ; i < this.currentPosition ; i++){ + stringBuilder.append(MARK); + } + return stringBuilder.toString(); +// return this.name + " : " + MARK.repeat(this.currentPosition); } @Override diff --git a/src/main/java/racingcar/model/car/OrderByPosition.java b/src/main/java/racingcar/model/car/OrderByPosition.java index bb88d4398c2..3e47c43f1a0 100644 --- a/src/main/java/racingcar/model/car/OrderByPosition.java +++ b/src/main/java/racingcar/model/car/OrderByPosition.java @@ -3,6 +3,6 @@ public class OrderByPosition implements OrderStrategy { @Override public int compare(Car o1, Car o2) { - return o1.currentPosition - o2.currentPosition; + return o1.currentPosition.compareTo(o2.currentPosition); } } diff --git a/src/test/java/racingcar/model/RoundTest.java b/src/test/java/racingcar/model/RoundTest.java index 76c2c9299bb..c0d2d47fc63 100644 --- a/src/test/java/racingcar/model/RoundTest.java +++ b/src/test/java/racingcar/model/RoundTest.java @@ -5,6 +5,7 @@ import org.junit.jupiter.params.provider.NullSource; import org.junit.jupiter.params.provider.ValueSource; +import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatThrownBy; class RoundTest { @@ -16,4 +17,11 @@ void checkInvalidRound(String value){ assertThatThrownBy(() -> new Round(value)).isInstanceOf(IllegalArgumentException.class); } + + @DisplayName("정상 횟수 입력 테스트") + @ParameterizedTest(name = "{displayName}: {0}") + @ValueSource(strings = {"120", "2", "2158249", "3213095803"}) + void checkValidRound(String value){ + assertThat(new Round(value).hasRound()).isTrue(); + } } From 481a1f045e5fd692678322f5a83e3453315efa3d Mon Sep 17 00:00:00 2001 From: JongHyunJung Date: Tue, 28 Nov 2023 21:53:56 +0900 Subject: [PATCH 31/44] =?UTF-8?q?refactor:=20=EC=83=81=EC=88=98=20?= =?UTF-8?q?=EC=82=AC=EC=9A=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/racingcar/model/Racer.java | 8 ++++---- src/main/java/racingcar/model/car/Car.java | 5 +++-- src/main/java/racingcar/type/MessageType.java | 16 ++++++++++++++++ .../racingcar/validation/RacerValidator.java | 6 +++--- src/main/java/racingcar/view/InputViewImpl.java | 7 +++++-- src/main/java/racingcar/view/OutputViewImpl.java | 4 +++- 6 files changed, 34 insertions(+), 12 deletions(-) create mode 100644 src/main/java/racingcar/type/MessageType.java diff --git a/src/main/java/racingcar/model/Racer.java b/src/main/java/racingcar/model/Racer.java index aec90d03dc4..1a46b7d317d 100644 --- a/src/main/java/racingcar/model/Racer.java +++ b/src/main/java/racingcar/model/Racer.java @@ -1,19 +1,19 @@ package racingcar.model; import racingcar.model.car.Car; -import racingcar.validation.RacerValidator; import racingcar.validation.Validator; import racingcar.validation.ValidatorFactory; +import static racingcar.type.MessageType.NAME_SEPARATOR; import java.util.Arrays; import java.util.List; public class Racer { - public static final String SEPERATOR = ","; +// public static final String SEPERATOR = ","; private final List racer; public Racer(String name) { validate(name); - this.racer = Arrays.stream(name.split(SEPERATOR)) + this.racer = Arrays.stream(name.split(NAME_SEPARATOR.getMessageValue())) .map(Car::new) .toList(); } @@ -55,7 +55,7 @@ public String winnerToString() { .map(Car::getName) .toList(); - return String.join(SEPERATOR + " ", winner); + return String.join(NAME_SEPARATOR + " ", winner); // List winner = getWinner(); // StringBuilder stringBuilder = new StringBuilder(); diff --git a/src/main/java/racingcar/model/car/Car.java b/src/main/java/racingcar/model/car/Car.java index 779010bc401..70d0a128794 100644 --- a/src/main/java/racingcar/model/car/Car.java +++ b/src/main/java/racingcar/model/car/Car.java @@ -1,15 +1,16 @@ package racingcar.model.car; import racingcar.service.ShiftGear; -import racingcar.validation.CarValidator; import racingcar.validation.Validator; import racingcar.validation.ValidatorFactory; import java.util.Comparator; +import static racingcar.type.MessageType.MARK; + // TODO : 자동차 경주에 말이 들어 온다면? public class Car { - private static final String MARK = "-"; +// private static final String MARK = "-"; // TODO : 어떻게 선언 할까 private final Comparator comparator = new OrderByPosition(); diff --git a/src/main/java/racingcar/type/MessageType.java b/src/main/java/racingcar/type/MessageType.java new file mode 100644 index 00000000000..6bb54b0eadd --- /dev/null +++ b/src/main/java/racingcar/type/MessageType.java @@ -0,0 +1,16 @@ +package racingcar.type; + +public enum MessageType { + MARK("-"), + NAME_SEPARATOR(","), + + ENTER_CAR_NAME("경주할 자동차 이름을 입력 하세요.(이름은 쉼표(,) 기준 으로 구분)"), + ENTER_RACE_ROUND("시도할 회수는 몇 회 인가요"), + ENTER_RACE_RESULT(System.lineSeparator() + "실행 결과"); + + private final String messageValue; + + MessageType(String messageValue) { this.messageValue = messageValue; } + + public String getMessageValue() { return messageValue; } +} diff --git a/src/main/java/racingcar/validation/RacerValidator.java b/src/main/java/racingcar/validation/RacerValidator.java index 2b48177c701..d1a86608732 100644 --- a/src/main/java/racingcar/validation/RacerValidator.java +++ b/src/main/java/racingcar/validation/RacerValidator.java @@ -3,9 +3,9 @@ import racingcar.model.Racer; import static racingcar.type.PlayType.MIN_PARTICIPANT; - +import static racingcar.type.MessageType.NAME_SEPARATOR; public class RacerValidator implements Validator { - public static final String SEPERATOR = ","; +// public static final String SEPERATOR = ","; @Override public boolean support(Class clazz) { return Racer.class.isAssignableFrom(clazz); @@ -17,7 +17,7 @@ public void validate(Object target) { } public void validateSize(String value){ - if (value == null || value.split(SEPERATOR).length < MIN_PARTICIPANT.getPlayValue()) { + if (value == null || value.split(NAME_SEPARATOR.getMessageValue()).length < MIN_PARTICIPANT.getPlayValue()) { throw new IllegalArgumentException("참가자가 없습니다."); } } diff --git a/src/main/java/racingcar/view/InputViewImpl.java b/src/main/java/racingcar/view/InputViewImpl.java index 0eff9e19c9a..96988f98e10 100644 --- a/src/main/java/racingcar/view/InputViewImpl.java +++ b/src/main/java/racingcar/view/InputViewImpl.java @@ -2,9 +2,12 @@ import camp.nextstep.edu.missionutils.Console; +import static racingcar.type.MessageType.ENTER_CAR_NAME; +import static racingcar.type.MessageType.ENTER_RACE_ROUND; + public class InputViewImpl implements InputView { - private static final String ENTER_CAR_NAME = "경주할 자동차 이름을 입력 하세요.(이름은 쉼표(,) 기준 으로 구분)"; - private static final String ENTER_RACE_ROUND = "시도할 회수는 몇 회 인가요?"; +// private static final String ENTER_CAR_NAME = "경주할 자동차 이름을 입력 하세요.(이름은 쉼표(,) 기준 으로 구분)"; +// private static final String ENTER_RACE_ROUND = "시도할 회수는 몇 회 인가요?"; @Override public String readCars() { System.out.println(ENTER_CAR_NAME); diff --git a/src/main/java/racingcar/view/OutputViewImpl.java b/src/main/java/racingcar/view/OutputViewImpl.java index 551c7375f72..dbb2b93dcc7 100644 --- a/src/main/java/racingcar/view/OutputViewImpl.java +++ b/src/main/java/racingcar/view/OutputViewImpl.java @@ -1,7 +1,9 @@ package racingcar.view; +import static racingcar.type.MessageType.ENTER_RACE_RESULT; + public class OutputViewImpl implements OutputView { - private static final String ENTER_RACE_RESULT = "\n실행 결과"; +// private static final String ENTER_RACE_RESULT = "\n실행 결과"; @Override public void printExecution() { System.out.println(ENTER_RACE_RESULT); From a29b932b5f96c3fa5fc654a4cba2bf5a5633fff9 Mon Sep 17 00:00:00 2001 From: JongHyunJung Date: Tue, 28 Nov 2023 22:18:10 +0900 Subject: [PATCH 32/44] =?UTF-8?q?refactor:=20=EC=98=88=EC=99=B8=20?= =?UTF-8?q?=EB=A9=94=EC=8B=9C=EC=A7=80=20=EB=A7=A4=EC=A7=81=20=EB=A6=AC?= =?UTF-8?q?=ED=84=B0=EB=9F=B4=20=EC=B9=98=ED=99=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/racingcar/model/Racer.java | 2 +- src/main/java/racingcar/model/car/Car.java | 2 +- .../racingcar/type/message/ErrorMessageType.java | 15 +++++++++++++++ .../racingcar/type/{ => message}/MessageType.java | 2 +- .../java/racingcar/validation/CarValidator.java | 8 ++++---- .../java/racingcar/validation/RacerValidator.java | 5 +++-- .../java/racingcar/validation/RoundValidator.java | 6 ++++-- src/main/java/racingcar/view/InputViewImpl.java | 4 ++-- src/main/java/racingcar/view/OutputViewImpl.java | 2 +- 9 files changed, 32 insertions(+), 14 deletions(-) create mode 100644 src/main/java/racingcar/type/message/ErrorMessageType.java rename src/main/java/racingcar/type/{ => message}/MessageType.java (93%) diff --git a/src/main/java/racingcar/model/Racer.java b/src/main/java/racingcar/model/Racer.java index 1a46b7d317d..ce79946f9d1 100644 --- a/src/main/java/racingcar/model/Racer.java +++ b/src/main/java/racingcar/model/Racer.java @@ -3,7 +3,7 @@ import racingcar.model.car.Car; import racingcar.validation.Validator; import racingcar.validation.ValidatorFactory; -import static racingcar.type.MessageType.NAME_SEPARATOR; +import static racingcar.type.message.MessageType.NAME_SEPARATOR; import java.util.Arrays; import java.util.List; diff --git a/src/main/java/racingcar/model/car/Car.java b/src/main/java/racingcar/model/car/Car.java index 70d0a128794..88e68763d6f 100644 --- a/src/main/java/racingcar/model/car/Car.java +++ b/src/main/java/racingcar/model/car/Car.java @@ -6,7 +6,7 @@ import java.util.Comparator; -import static racingcar.type.MessageType.MARK; +import static racingcar.type.message.MessageType.MARK; // TODO : 자동차 경주에 말이 들어 온다면? public class Car { diff --git a/src/main/java/racingcar/type/message/ErrorMessageType.java b/src/main/java/racingcar/type/message/ErrorMessageType.java new file mode 100644 index 00000000000..b592678bc2d --- /dev/null +++ b/src/main/java/racingcar/type/message/ErrorMessageType.java @@ -0,0 +1,15 @@ +package racingcar.type.message; +import static racingcar.type.PlayType.*; +public enum ErrorMessageType { + INVALID_LENGTH(String.format("이름의 길이는 %s 이상 %s 이하여야 합니다.", MIN_LENGTH, MAX_LENGTH)), + BLANK_SPACE("이름은 공백이 아니어야 합니다."), + NO_PARTICIPANT("참가자가 없습니다."), + INVALID_TYPE("잘못된 타입 입니다."), + INVALID_RANGE("잘못된 범위 입니다."); + + private final String errorMessageValue; + + ErrorMessageType(String errorMessageValue) { this.errorMessageValue = errorMessageValue; } + + public String getErrorMessageValue() { return errorMessageValue; } +} diff --git a/src/main/java/racingcar/type/MessageType.java b/src/main/java/racingcar/type/message/MessageType.java similarity index 93% rename from src/main/java/racingcar/type/MessageType.java rename to src/main/java/racingcar/type/message/MessageType.java index 6bb54b0eadd..221cdeab802 100644 --- a/src/main/java/racingcar/type/MessageType.java +++ b/src/main/java/racingcar/type/message/MessageType.java @@ -1,4 +1,4 @@ -package racingcar.type; +package racingcar.type.message; public enum MessageType { MARK("-"), diff --git a/src/main/java/racingcar/validation/CarValidator.java b/src/main/java/racingcar/validation/CarValidator.java index 34af3854d64..495652a4d2a 100644 --- a/src/main/java/racingcar/validation/CarValidator.java +++ b/src/main/java/racingcar/validation/CarValidator.java @@ -2,8 +2,8 @@ import racingcar.model.car.Car; -import static racingcar.type.PlayType.MAX_LENGTH; -import static racingcar.type.PlayType.MIN_LENGTH; +import static racingcar.type.PlayType.*; +import static racingcar.type.message.ErrorMessageType.*; public class CarValidator implements Validator { @Override @@ -19,13 +19,13 @@ public void validate(Object target) { private void validateLength(String value){ if(MIN_LENGTH.getPlayValue() > value.length() || value.length() > MAX_LENGTH.getPlayValue()){ - throw new IllegalArgumentException(); + throw new IllegalArgumentException(INVALID_LENGTH.getErrorMessageValue()); } } private void validateSpace(String value){ if (value.trim().equals("")){ - throw new IllegalArgumentException(); + throw new IllegalArgumentException(BLANK_SPACE.getErrorMessageValue()); } } } diff --git a/src/main/java/racingcar/validation/RacerValidator.java b/src/main/java/racingcar/validation/RacerValidator.java index d1a86608732..cf794749cce 100644 --- a/src/main/java/racingcar/validation/RacerValidator.java +++ b/src/main/java/racingcar/validation/RacerValidator.java @@ -3,7 +3,8 @@ import racingcar.model.Racer; import static racingcar.type.PlayType.MIN_PARTICIPANT; -import static racingcar.type.MessageType.NAME_SEPARATOR; +import static racingcar.type.message.MessageType.NAME_SEPARATOR; +import static racingcar.type.message.ErrorMessageType.NO_PARTICIPANT; public class RacerValidator implements Validator { // public static final String SEPERATOR = ","; @Override @@ -18,7 +19,7 @@ public void validate(Object target) { public void validateSize(String value){ if (value == null || value.split(NAME_SEPARATOR.getMessageValue()).length < MIN_PARTICIPANT.getPlayValue()) { - throw new IllegalArgumentException("참가자가 없습니다."); + throw new IllegalArgumentException(NO_PARTICIPANT.getErrorMessageValue()); } } } diff --git a/src/main/java/racingcar/validation/RoundValidator.java b/src/main/java/racingcar/validation/RoundValidator.java index 0b1a11970f8..14dbcdecc33 100644 --- a/src/main/java/racingcar/validation/RoundValidator.java +++ b/src/main/java/racingcar/validation/RoundValidator.java @@ -4,6 +4,8 @@ import static racingcar.type.PlayType.MAX_NUM; import static racingcar.type.PlayType.MIN_NUM; +import static racingcar.type.message.ErrorMessageType.INVALID_TYPE; +import static racingcar.type.message.ErrorMessageType.INVALID_RANGE; public class RoundValidator implements Validator { public static final String VALID_RANGE = "^["+ MIN_NUM + "-" + MAX_NUM +"]+"; @@ -20,13 +22,13 @@ public void validate(Object target) { private void validateType(String value){ if (value != null && !value.matches(VALID_RANGE)){ - throw new IllegalArgumentException(); + throw new IllegalArgumentException(INVALID_TYPE.getErrorMessageValue()); } } private void validateRange(String value){ if (0 > Integer.parseInt(value)) { - throw new IllegalArgumentException(); + throw new IllegalArgumentException(INVALID_RANGE.getErrorMessageValue()); } } } diff --git a/src/main/java/racingcar/view/InputViewImpl.java b/src/main/java/racingcar/view/InputViewImpl.java index 96988f98e10..0a55578df0e 100644 --- a/src/main/java/racingcar/view/InputViewImpl.java +++ b/src/main/java/racingcar/view/InputViewImpl.java @@ -2,8 +2,8 @@ import camp.nextstep.edu.missionutils.Console; -import static racingcar.type.MessageType.ENTER_CAR_NAME; -import static racingcar.type.MessageType.ENTER_RACE_ROUND; +import static racingcar.type.message.MessageType.ENTER_CAR_NAME; +import static racingcar.type.message.MessageType.ENTER_RACE_ROUND; public class InputViewImpl implements InputView { // private static final String ENTER_CAR_NAME = "경주할 자동차 이름을 입력 하세요.(이름은 쉼표(,) 기준 으로 구분)"; diff --git a/src/main/java/racingcar/view/OutputViewImpl.java b/src/main/java/racingcar/view/OutputViewImpl.java index dbb2b93dcc7..ee13d729e72 100644 --- a/src/main/java/racingcar/view/OutputViewImpl.java +++ b/src/main/java/racingcar/view/OutputViewImpl.java @@ -1,6 +1,6 @@ package racingcar.view; -import static racingcar.type.MessageType.ENTER_RACE_RESULT; +import static racingcar.type.message.MessageType.ENTER_RACE_RESULT; public class OutputViewImpl implements OutputView { // private static final String ENTER_RACE_RESULT = "\n실행 결과"; From be86df08ea9bc81853f82b2e19a4438e01be6114 Mon Sep 17 00:00:00 2001 From: JongHyunJung Date: Tue, 28 Nov 2023 22:23:37 +0900 Subject: [PATCH 33/44] =?UTF-8?q?refactor:=20=EC=B6=9C=EB=A0=A5=20?= =?UTF-8?q?=EB=A9=94=EC=8B=9C=EC=A7=80=20=EB=A7=A4=EC=A7=81=20=EB=A6=AC?= =?UTF-8?q?=ED=84=B0=EB=9F=B4=20=EC=B9=98=ED=99=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/racingcar/controller/RacingCarController.java | 2 +- src/main/java/racingcar/type/message/MessageType.java | 3 ++- src/main/java/racingcar/view/OutputView.java | 2 +- src/main/java/racingcar/view/OutputViewImpl.java | 5 +++-- 4 files changed, 7 insertions(+), 5 deletions(-) diff --git a/src/main/java/racingcar/controller/RacingCarController.java b/src/main/java/racingcar/controller/RacingCarController.java index 411b47e8c3a..dd5979ea3c9 100644 --- a/src/main/java/racingcar/controller/RacingCarController.java +++ b/src/main/java/racingcar/controller/RacingCarController.java @@ -28,7 +28,7 @@ public void run(){ // position.put(name, 0); // } - outputView.printExecution(); + outputView.printExecutionResult(); // 라운드 별 각각의 레이서 결과 출력 while(round.hasRound()){ racer.play(); diff --git a/src/main/java/racingcar/type/message/MessageType.java b/src/main/java/racingcar/type/message/MessageType.java index 221cdeab802..746743d6210 100644 --- a/src/main/java/racingcar/type/message/MessageType.java +++ b/src/main/java/racingcar/type/message/MessageType.java @@ -6,7 +6,8 @@ public enum MessageType { ENTER_CAR_NAME("경주할 자동차 이름을 입력 하세요.(이름은 쉼표(,) 기준 으로 구분)"), ENTER_RACE_ROUND("시도할 회수는 몇 회 인가요"), - ENTER_RACE_RESULT(System.lineSeparator() + "실행 결과"); + ENTER_RACE_RESULT("\n실행 결과"), + FINAL_WINNER("최종 우승자 : %s"); private final String messageValue; diff --git a/src/main/java/racingcar/view/OutputView.java b/src/main/java/racingcar/view/OutputView.java index b0cb586753e..da4d724fc28 100644 --- a/src/main/java/racingcar/view/OutputView.java +++ b/src/main/java/racingcar/view/OutputView.java @@ -1,7 +1,7 @@ package racingcar.view; public interface OutputView { - void printExecution(); + void printExecutionResult(); void printResult(String result); diff --git a/src/main/java/racingcar/view/OutputViewImpl.java b/src/main/java/racingcar/view/OutputViewImpl.java index ee13d729e72..e44a7fef92f 100644 --- a/src/main/java/racingcar/view/OutputViewImpl.java +++ b/src/main/java/racingcar/view/OutputViewImpl.java @@ -1,11 +1,12 @@ package racingcar.view; import static racingcar.type.message.MessageType.ENTER_RACE_RESULT; +import static racingcar.type.message.MessageType.FINAL_WINNER; public class OutputViewImpl implements OutputView { // private static final String ENTER_RACE_RESULT = "\n실행 결과"; @Override - public void printExecution() { + public void printExecutionResult() { System.out.println(ENTER_RACE_RESULT); } @@ -16,6 +17,6 @@ public void printResult(String result) { @Override public void printFinalWinner(String winner) { - System.out.print("최종 우승자 : " + winner); + System.out.printf(FINAL_WINNER.getMessageValue(), winner); } } From d50e51d13d724dd0c903db2b0ac36b747e596ed8 Mon Sep 17 00:00:00 2001 From: JongHyunJung Date: Tue, 28 Nov 2023 22:32:29 +0900 Subject: [PATCH 34/44] =?UTF-8?q?feat:=20=EA=B2=BD=EC=A3=BC=ED=95=A0=20?= =?UTF-8?q?=EC=9E=90=EB=8F=99=EC=B0=A8=20=EC=A4=91=20=EC=A4=91=EB=B3=B5?= =?UTF-8?q?=EB=90=9C=20=EC=9D=B4=EB=A6=84=EC=9D=B4=20=EC=9E=88=EB=8A=94=20?= =?UTF-8?q?=EA=B2=BD=EC=9A=B0=20=EC=98=88=EC=99=B8=20=EC=B2=98=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/README.md | 2 +- .../java/racingcar/type/message/ErrorMessageType.java | 3 ++- src/main/java/racingcar/validation/RacerValidator.java | 10 ++++++++++ src/test/java/racingcar/model/RacerTest.java | 8 ++++++++ 4 files changed, 21 insertions(+), 2 deletions(-) diff --git a/docs/README.md b/docs/README.md index b24683e6bfe..4164b09a4cc 100644 --- a/docs/README.md +++ b/docs/README.md @@ -23,7 +23,7 @@ * [x] 경주할 자동차 없는 경우 * [x] 경주할 자동차 이름이 1 이상 5 이하가 아닌 경우 * [x] 경주할 자동차 이름이 공백인 경우 -* [ ] 경주할 자동차 중 중복된 이름이 있는 경우 +* [x] 경주할 자동차 중 중복된 이름이 있는 경우 * [ ] 경주할 자동차 구분자 "," 가 아닌 경우 * [x] 시도할 횟수가 자연수 아닌 경우 diff --git a/src/main/java/racingcar/type/message/ErrorMessageType.java b/src/main/java/racingcar/type/message/ErrorMessageType.java index b592678bc2d..3a0360f7e65 100644 --- a/src/main/java/racingcar/type/message/ErrorMessageType.java +++ b/src/main/java/racingcar/type/message/ErrorMessageType.java @@ -5,7 +5,8 @@ public enum ErrorMessageType { BLANK_SPACE("이름은 공백이 아니어야 합니다."), NO_PARTICIPANT("참가자가 없습니다."), INVALID_TYPE("잘못된 타입 입니다."), - INVALID_RANGE("잘못된 범위 입니다."); + INVALID_RANGE("잘못된 범위 입니다."), + INVALID_UNIQUE("중복 입니다."); private final String errorMessageValue; diff --git a/src/main/java/racingcar/validation/RacerValidator.java b/src/main/java/racingcar/validation/RacerValidator.java index cf794749cce..5f604af58ae 100644 --- a/src/main/java/racingcar/validation/RacerValidator.java +++ b/src/main/java/racingcar/validation/RacerValidator.java @@ -2,7 +2,10 @@ import racingcar.model.Racer; +import java.util.Set; + import static racingcar.type.PlayType.MIN_PARTICIPANT; +import static racingcar.type.message.ErrorMessageType.INVALID_UNIQUE; import static racingcar.type.message.MessageType.NAME_SEPARATOR; import static racingcar.type.message.ErrorMessageType.NO_PARTICIPANT; public class RacerValidator implements Validator { @@ -15,6 +18,7 @@ public boolean support(Class clazz) { @Override public void validate(Object target) { validateSize((String) target); + validateUnique((String) target); } public void validateSize(String value){ @@ -22,4 +26,10 @@ public void validateSize(String value){ throw new IllegalArgumentException(NO_PARTICIPANT.getErrorMessageValue()); } } + + public void validateUnique(String value){ + if (Set.of(value.split(NAME_SEPARATOR.getMessageValue())).size() != value.split(NAME_SEPARATOR.getMessageValue()).length){ + throw new IllegalArgumentException(INVALID_UNIQUE.getErrorMessageValue()); + } + } } diff --git a/src/test/java/racingcar/model/RacerTest.java b/src/test/java/racingcar/model/RacerTest.java index 95f2a57669b..51dc9546b52 100644 --- a/src/test/java/racingcar/model/RacerTest.java +++ b/src/test/java/racingcar/model/RacerTest.java @@ -16,4 +16,12 @@ void checkRacer(String value){ assertThatThrownBy(() -> new Racer(value)) .isInstanceOf(IllegalArgumentException.class); } + + @DisplayName("중복된 이름 체크") + @ParameterizedTest + @ValueSource(strings = {"ad, k, la, a, la", "l, l", "qwe, kz, pi, pi"}) + void checkUnique(String value){ + assertThatThrownBy(() -> new Racer(value)) + .isInstanceOf(IllegalArgumentException.class); + } } From 5222ff4bef909ae1ab469d8ef7bf05f54f7578ac Mon Sep 17 00:00:00 2001 From: JongHyunJung Date: Tue, 28 Nov 2023 22:41:37 +0900 Subject: [PATCH 35/44] =?UTF-8?q?test:=20=EC=98=AC=EB=B0=94=EB=A5=B8=20?= =?UTF-8?q?=EB=B2=94=EC=9C=84=20=EB=9E=9C=EB=8D=A4=20=EC=88=AB=EC=9E=90=20?= =?UTF-8?q?=EC=83=9D=EC=84=B1=20=ED=85=8C=EC=8A=A4=ED=8A=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../racingcar/service/NumberGenerator.java | 5 +++++ .../service/RandomNumberGenerator.java | 13 +++++++++++++ .../util/RandomNumberGeneratorTest.java | 19 +++++++++++++++++++ 3 files changed, 37 insertions(+) create mode 100644 src/main/java/racingcar/service/NumberGenerator.java create mode 100644 src/main/java/racingcar/service/RandomNumberGenerator.java create mode 100644 src/test/java/racingcar/util/RandomNumberGeneratorTest.java diff --git a/src/main/java/racingcar/service/NumberGenerator.java b/src/main/java/racingcar/service/NumberGenerator.java new file mode 100644 index 00000000000..3053505449b --- /dev/null +++ b/src/main/java/racingcar/service/NumberGenerator.java @@ -0,0 +1,5 @@ +package racingcar.service; + +public interface NumberGenerator { + int generate(); +} diff --git a/src/main/java/racingcar/service/RandomNumberGenerator.java b/src/main/java/racingcar/service/RandomNumberGenerator.java new file mode 100644 index 00000000000..77fe4460315 --- /dev/null +++ b/src/main/java/racingcar/service/RandomNumberGenerator.java @@ -0,0 +1,13 @@ +package racingcar.service; + +import camp.nextstep.edu.missionutils.Randoms; + +import static racingcar.type.PlayType.MAX_NUM; +import static racingcar.type.PlayType.MIN_NUM; + +public class RandomNumberGenerator implements NumberGenerator{ + @Override + public int generate() { + return Randoms.pickNumberInRange(MIN_NUM.getPlayValue(), MAX_NUM.getPlayValue()); + } +} diff --git a/src/test/java/racingcar/util/RandomNumberGeneratorTest.java b/src/test/java/racingcar/util/RandomNumberGeneratorTest.java new file mode 100644 index 00000000000..443bb901f49 --- /dev/null +++ b/src/test/java/racingcar/util/RandomNumberGeneratorTest.java @@ -0,0 +1,19 @@ +package racingcar.util; + +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import racingcar.service.RandomNumberGenerator; + +import static org.assertj.core.api.Assertions.assertThat; + +public class RandomNumberGeneratorTest { + @DisplayName("올바른 범위의 랜덤한 숫자 생성") + @Test + void checkRandomNumberGenerate(){ + RandomNumberGenerator numberGenerator = new RandomNumberGenerator(); + int t = 10; + while (t --> 0){ + assertThat(numberGenerator.generate()).isBetween(0,9); + } + } +} From d2b13de37df6e4e4192ecc0b7e225840ea9922f8 Mon Sep 17 00:00:00 2001 From: JongHyunJung Date: Tue, 28 Nov 2023 22:46:25 +0900 Subject: [PATCH 36/44] =?UTF-8?q?refactor:=20=EC=A0=95=EA=B7=9C=EC=8B=9D?= =?UTF-8?q?=EC=9D=84=20Pattern=20=EC=A0=95=EC=A0=81=20=EA=B0=9D=EC=B2=B4?= =?UTF-8?q?=EB=A1=9C=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/racingcar/validation/RoundValidator.java | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/main/java/racingcar/validation/RoundValidator.java b/src/main/java/racingcar/validation/RoundValidator.java index 14dbcdecc33..111d0210baf 100644 --- a/src/main/java/racingcar/validation/RoundValidator.java +++ b/src/main/java/racingcar/validation/RoundValidator.java @@ -2,6 +2,8 @@ import racingcar.model.Round; +import java.util.regex.Pattern; + import static racingcar.type.PlayType.MAX_NUM; import static racingcar.type.PlayType.MIN_NUM; import static racingcar.type.message.ErrorMessageType.INVALID_TYPE; @@ -9,6 +11,7 @@ public class RoundValidator implements Validator { public static final String VALID_RANGE = "^["+ MIN_NUM + "-" + MAX_NUM +"]+"; + private static final Pattern NUMBER = Pattern.compile(VALID_RANGE); @Override public boolean support(Class clazz) { return Round.class.isAssignableFrom(clazz); @@ -21,7 +24,8 @@ public void validate(Object target) { } private void validateType(String value){ - if (value != null && !value.matches(VALID_RANGE)){ +// if (value != null && !value.matches(VALID_RANGE)){ + if (value != null & !NUMBER.matcher(value).matches()){ throw new IllegalArgumentException(INVALID_TYPE.getErrorMessageValue()); } } From 9b77dce777b138f3fde196928be17d15d1ab3ece Mon Sep 17 00:00:00 2001 From: JongHyunJung Date: Tue, 28 Nov 2023 22:58:11 +0900 Subject: [PATCH 37/44] =?UTF-8?q?refactor:=20=EC=A0=95=EB=A0=AC=20?= =?UTF-8?q?=EC=A1=B0=EA=B1=B4=20=ED=8C=8C=EB=9D=BC=EB=AF=B8=ED=84=B0=20?= =?UTF-8?q?=EC=A3=BC=EC=9E=85=EC=9C=BC=EB=A1=9C=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/racingcar/model/Racer.java | 21 ++++++++++++++++----- src/main/java/racingcar/model/car/Car.java | 12 +++++------- 2 files changed, 21 insertions(+), 12 deletions(-) diff --git a/src/main/java/racingcar/model/Racer.java b/src/main/java/racingcar/model/Racer.java index ce79946f9d1..c185bcef994 100644 --- a/src/main/java/racingcar/model/Racer.java +++ b/src/main/java/racingcar/model/Racer.java @@ -1,6 +1,8 @@ package racingcar.model; import racingcar.model.car.Car; +import racingcar.model.car.OrderByPosition; +import racingcar.model.car.OrderStrategy; import racingcar.validation.Validator; import racingcar.validation.ValidatorFactory; import static racingcar.type.message.MessageType.NAME_SEPARATOR; @@ -39,18 +41,27 @@ private void validate(String value){ // .collect(Collectors.joining(SEPERATOR)); // } - public List getWinner() { - Car first = racer.stream() - .max(Car::compareTo) - .orElseThrow(IllegalAccessError::new); +// public List getWinner() { +// Car first = racer.stream() +// .max(Car::compareTo) +// .orElseThrow(IllegalAccessError::new); +// +// return racer.stream() +// .filter(car -> car.equals(first)) +// .toList(); +// } + public List getWinner(OrderStrategy orderStrategy){ + Car first = racer.stream() + .max(orderStrategy) + .orElseThrow(); return racer.stream() .filter(car -> car.equals(first)) .toList(); } public String winnerToString() { - List winner = getWinner() + List winner = getWinner(new OrderByPosition()) .stream() .map(Car::getName) .toList(); diff --git a/src/main/java/racingcar/model/car/Car.java b/src/main/java/racingcar/model/car/Car.java index 88e68763d6f..67251b45e96 100644 --- a/src/main/java/racingcar/model/car/Car.java +++ b/src/main/java/racingcar/model/car/Car.java @@ -4,15 +4,13 @@ import racingcar.validation.Validator; import racingcar.validation.ValidatorFactory; -import java.util.Comparator; - import static racingcar.type.message.MessageType.MARK; // TODO : 자동차 경주에 말이 들어 온다면? public class Car { // private static final String MARK = "-"; // TODO : 어떻게 선언 할까 - private final Comparator comparator = new OrderByPosition(); +// private final Comparator comparator = new OrderByPosition(); protected final String name; protected Long currentPosition; @@ -67,10 +65,10 @@ public boolean equals(Object obj){ return this.currentPosition.equals(car.currentPosition); } - public int compareTo(Car car) { - return comparator.compare(this, car); -// return this.currentPosition - car.currentPosition; - } +// public int compareTo(Car car) { +// return comparator.compare(this, car); +//// return this.currentPosition - car.currentPosition; +// } // private void validateName(String name){ // validateLength(name); From d2d01d3ebb0a7075d8cba2bb36bdb70f4d893016 Mon Sep 17 00:00:00 2001 From: JongHyunJung Date: Fri, 1 Dec 2023 06:53:11 +0900 Subject: [PATCH 38/44] =?UTF-8?q?refactor:=20stream()=20API=20=ED=99=9C?= =?UTF-8?q?=EC=9A=A9=20(collect)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/racingcar/model/Racer.java | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/src/main/java/racingcar/model/Racer.java b/src/main/java/racingcar/model/Racer.java index c185bcef994..37a700fa799 100644 --- a/src/main/java/racingcar/model/Racer.java +++ b/src/main/java/racingcar/model/Racer.java @@ -9,6 +9,7 @@ import java.util.Arrays; import java.util.List; +import java.util.stream.Collectors; public class Racer { // public static final String SEPERATOR = ","; @@ -61,12 +62,17 @@ public List getWinner(OrderStrategy orderStrategy){ } public String winnerToString() { - List winner = getWinner(new OrderByPosition()) + return getWinner(new OrderByPosition()) .stream() .map(Car::getName) - .toList(); + .collect(Collectors.joining(NAME_SEPARATOR + " ")); - return String.join(NAME_SEPARATOR + " ", winner); +// List winner = getWinner(new OrderByPosition()) +// .stream() +// .map(Car::getName) +// .toList(); +// +// return String.join(NAME_SEPARATOR + " ", winner); // List winner = getWinner(); // StringBuilder stringBuilder = new StringBuilder(); From ef783dbcbb611c57e29c09cbd824a125eac6eb6d Mon Sep 17 00:00:00 2001 From: JongHyunJung Date: Fri, 1 Dec 2023 06:58:06 +0900 Subject: [PATCH 39/44] =?UTF-8?q?refactor:=20Round=20=EC=A0=95=EC=A0=81=20?= =?UTF-8?q?=ED=8C=A9=ED=86=A0=EB=A6=AC=20=EB=A9=94=EC=84=9C=EB=93=9C=20?= =?UTF-8?q?=EC=A0=81=EC=9A=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/racingcar/controller/RacingCarController.java | 4 ++-- src/main/java/racingcar/model/Round.java | 6 +++++- src/test/java/racingcar/model/RoundTest.java | 4 ++-- 3 files changed, 9 insertions(+), 5 deletions(-) diff --git a/src/main/java/racingcar/controller/RacingCarController.java b/src/main/java/racingcar/controller/RacingCarController.java index dd5979ea3c9..849d904070b 100644 --- a/src/main/java/racingcar/controller/RacingCarController.java +++ b/src/main/java/racingcar/controller/RacingCarController.java @@ -20,8 +20,8 @@ public void run(){ // List names = List.of(resultCars.split(",")); Racer racer = new Racer(inputView.readCars()); // int round = Integer.parseInt(inputView.readRaceRound()); - Round round = new Round(inputView.readRound()); - +// Round round = new Round(inputView.readRound()); + Round round = Round.of(inputView.readRound()); // 각각의 racer 초기화 // Map position = new LinkedHashMap<>(); // for(String name: names){ diff --git a/src/main/java/racingcar/model/Round.java b/src/main/java/racingcar/model/Round.java index 370541f026b..c3c959a3c0d 100644 --- a/src/main/java/racingcar/model/Round.java +++ b/src/main/java/racingcar/model/Round.java @@ -11,11 +11,15 @@ public class Round { private Long round; // private Integer round; - public Round(String round){ + private Round(String round){ validate(round); this.round = Long.valueOf(round); } + public static Round of(String round){ + return new Round(round); + } + // TODO: 진행 중인지 확인 하는 것 뿐 아니라 감소도 함 // public Boolean isContinue(){ // if (round > 0){ diff --git a/src/test/java/racingcar/model/RoundTest.java b/src/test/java/racingcar/model/RoundTest.java index c0d2d47fc63..2a447c048ad 100644 --- a/src/test/java/racingcar/model/RoundTest.java +++ b/src/test/java/racingcar/model/RoundTest.java @@ -15,13 +15,13 @@ class RoundTest { @NullSource void checkInvalidRound(String value){ assertThatThrownBy(() -> - new Round(value)).isInstanceOf(IllegalArgumentException.class); + Round.of(value)).isInstanceOf(IllegalArgumentException.class); } @DisplayName("정상 횟수 입력 테스트") @ParameterizedTest(name = "{displayName}: {0}") @ValueSource(strings = {"120", "2", "2158249", "3213095803"}) void checkValidRound(String value){ - assertThat(new Round(value).hasRound()).isTrue(); + assertThat(Round.of(value).hasRound()).isTrue(); } } From 9d9b5b0c228eadfaef2cac624e8d10f1a875b91a Mon Sep 17 00:00:00 2001 From: JongHyunJung Date: Fri, 1 Dec 2023 07:04:34 +0900 Subject: [PATCH 40/44] =?UTF-8?q?refactor:=20=EB=A9=94=EC=84=9C=EB=93=9C?= =?UTF-8?q?=EA=B0=80=20=ED=95=9C=EA=B0=80=EC=A7=80=20=EC=9D=BC=EB=A7=8C=20?= =?UTF-8?q?=ED=95=98=EB=8F=84=EB=A1=9D=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/racingcar/controller/RacingCarController.java | 1 + src/main/java/racingcar/model/Round.java | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/src/main/java/racingcar/controller/RacingCarController.java b/src/main/java/racingcar/controller/RacingCarController.java index 849d904070b..8d5a14c1767 100644 --- a/src/main/java/racingcar/controller/RacingCarController.java +++ b/src/main/java/racingcar/controller/RacingCarController.java @@ -33,6 +33,7 @@ public void run(){ while(round.hasRound()){ racer.play(); outputView.printResult(racer.toString()); + round.turn(); } // for (int i=0 ; i < round ; i++){ // racer.play(); diff --git a/src/main/java/racingcar/model/Round.java b/src/main/java/racingcar/model/Round.java index c3c959a3c0d..46bf60bb80a 100644 --- a/src/main/java/racingcar/model/Round.java +++ b/src/main/java/racingcar/model/Round.java @@ -29,7 +29,7 @@ public static Round of(String round){ // return false; // } public Boolean hasRound(){ - turn(); +// turn(); return round >= 0; } From 340982f7171e51d40674730a64389e4c5802c897 Mon Sep 17 00:00:00 2001 From: JongHyunJung Date: Fri, 1 Dec 2023 07:06:47 +0900 Subject: [PATCH 41/44] =?UTF-8?q?refactor:=20controller=20=ED=81=B4?= =?UTF-8?q?=EB=9E=98=EC=8A=A4=20=EB=A9=94=EC=84=9C=EB=93=9C=20=EB=B6=84?= =?UTF-8?q?=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/racingcar/controller/RacingCarController.java | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/src/main/java/racingcar/controller/RacingCarController.java b/src/main/java/racingcar/controller/RacingCarController.java index 8d5a14c1767..95c178d90d3 100644 --- a/src/main/java/racingcar/controller/RacingCarController.java +++ b/src/main/java/racingcar/controller/RacingCarController.java @@ -31,8 +31,9 @@ public void run(){ outputView.printExecutionResult(); // 라운드 별 각각의 레이서 결과 출력 while(round.hasRound()){ - racer.play(); - outputView.printResult(racer.toString()); + play(racer); +// racer.play(); +// outputView.printResult(racer.toString()); round.turn(); } // for (int i=0 ; i < round ; i++){ @@ -46,6 +47,11 @@ public void run(){ outputView.printFinalWinner(racer.winnerToString()); } + private void play(Racer racer){ + racer.play(); + outputView.printResult(racer.toString()); + } + // private void play(Map position) { // for (String name : position.keySet()){ // if (ShiftGear.moveForward()) { From 527ae0bf0d654b855560856a7265f0f963abcb89 Mon Sep 17 00:00:00 2001 From: JongHyunJung Date: Fri, 1 Dec 2023 07:40:39 +0900 Subject: [PATCH 42/44] =?UTF-8?q?refactor:=20Car=20=EC=A0=95=EC=A0=81=20?= =?UTF-8?q?=ED=8C=A9=ED=86=A0=EB=A6=AC=20=EB=A9=94=EC=84=9C=EB=93=9C=20?= =?UTF-8?q?=EC=82=AC=EC=9A=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/racingcar/model/Racer.java | 2 +- src/main/java/racingcar/model/car/Car.java | 8 ++++++-- src/test/java/racingcar/model/CarTest.java | 2 +- 3 files changed, 8 insertions(+), 4 deletions(-) diff --git a/src/main/java/racingcar/model/Racer.java b/src/main/java/racingcar/model/Racer.java index 37a700fa799..9c8281e46f0 100644 --- a/src/main/java/racingcar/model/Racer.java +++ b/src/main/java/racingcar/model/Racer.java @@ -17,7 +17,7 @@ public class Racer { public Racer(String name) { validate(name); this.racer = Arrays.stream(name.split(NAME_SEPARATOR.getMessageValue())) - .map(Car::new) + .map(Car::ofStartPoint) .toList(); } diff --git a/src/main/java/racingcar/model/car/Car.java b/src/main/java/racingcar/model/car/Car.java index 67251b45e96..9fe92c37e58 100644 --- a/src/main/java/racingcar/model/car/Car.java +++ b/src/main/java/racingcar/model/car/Car.java @@ -15,10 +15,14 @@ public class Car { protected final String name; protected Long currentPosition; - public Car(String name){ + private Car(String name, Long currentPosition){ validate(name); this.name = name; - this.currentPosition = 0L; + this.currentPosition = currentPosition; + } + + public static Car ofStartPoint(String name){ + return new Car(name, 0L); } public void move() { diff --git a/src/test/java/racingcar/model/CarTest.java b/src/test/java/racingcar/model/CarTest.java index 1ee11a871dd..d07f7e6d2ff 100644 --- a/src/test/java/racingcar/model/CarTest.java +++ b/src/test/java/racingcar/model/CarTest.java @@ -12,7 +12,7 @@ class CarTest { @ParameterizedTest(name = "{displayName} value = {0}") @ValueSource(strings = {"myCarIsKia", "myName", " "}) void checkValidateLength(String name){ - assertThatThrownBy(() -> new Car(name)) + assertThatThrownBy(() -> Car.ofStartPoint(name)) .isInstanceOf(IllegalArgumentException.class); } } From eb259c76710652307ce18a1873db03bfa73d350b Mon Sep 17 00:00:00 2001 From: JongHyunJung Date: Fri, 1 Dec 2023 07:44:57 +0900 Subject: [PATCH 43/44] =?UTF-8?q?test:=20Round=20=ED=94=8C=EB=A0=88?= =?UTF-8?q?=EC=9D=B4=20=ED=85=8C=EC=8A=A4=ED=8A=B8=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/test/java/racingcar/model/RoundTest.java | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/src/test/java/racingcar/model/RoundTest.java b/src/test/java/racingcar/model/RoundTest.java index 2a447c048ad..34b4dac2d7e 100644 --- a/src/test/java/racingcar/model/RoundTest.java +++ b/src/test/java/racingcar/model/RoundTest.java @@ -24,4 +24,17 @@ void checkInvalidRound(String value){ void checkValidRound(String value){ assertThat(Round.of(value).hasRound()).isTrue(); } + + @DisplayName("라운드 플레이 테스트") + @ParameterizedTest(name = "{displayName}: {0}") + @ValueSource(strings = {"3", "5", "100", "0"}) + void checkRoundPlay(String value){ + Round round = Round.of(value); + long count = Long.parseLong(value); + while(round.hasRound()) { + round.turn(); + count--; + } + assertThat(count).isEqualTo(-1); + } } From c0715df77c01519aeac7cb4a609ed9ef31a0dd13 Mon Sep 17 00:00:00 2001 From: JongHyunJung Date: Fri, 1 Dec 2023 07:47:38 +0900 Subject: [PATCH 44/44] =?UTF-8?q?doc:=20=EA=B3=A0=EB=AF=BC=ED=95=B4?= =?UTF-8?q?=EB=B3=BC=20=EC=A3=BC=EC=A0=9C=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/README.md | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/docs/README.md b/docs/README.md index 4164b09a4cc..6762d340859 100644 --- a/docs/README.md +++ b/docs/README.md @@ -38,9 +38,10 @@ * [ ] interface 활용 (메세지 던지기) * [x] Integer 대신 Long 사용 고려 -## 고민해볼 주제 - -* [ ] 마지막 ,로 끝나는 경우 +## 고민해 볼 주제 +* [X] 마지막 ,로 끝나는 경우 + * 해당 경우 예외 처리 하지 않음 + * new String[]{"1", "3", }; 같은 경우도 가능 하기 때문 * [ ] 각 차수별 실행 결과 출력의 순서 * 사용자 입력 순 * 사전 정렬 순 \ No newline at end of file