-
Notifications
You must be signed in to change notification settings - Fork 55
[이관우_BackEnd] 1주차 과제 제출합니다. #63
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
69d278c
9229ec4
685fe5a
40da36d
61d357e
7bbb90e
f64079a
a7ff546
45ea126
37fa75d
3225b97
8b31444
50e6030
279705a
a2c3577
8d25826
d728091
7da49d6
84f9b6f
7313a94
7fba792
d7231b8
cb66dfc
014e73c
f1e0633
2ac8837
4a8e1f0
a96b0a3
b6e5763
903d754
12502f4
dcede87
b93d0f6
593e6cc
0b2d351
69b3c01
dc2bbdd
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,30 @@ | ||
| ## 구현해야 하는 기능 목록 | ||
|
|
||
| ### 자동차 | ||
| - [x] 클래스 기본 틀 작성(변수, 생성자 등) | ||
| - [x] 랜덤 수(0~9) 반환 메소드 | ||
| - [x] 자동차를 한 칸 전진하는 메소드 | ||
|
|
||
| ### 입력 | ||
| - [x] 자동차 이름 & 입력 횟수 입력 | ||
| - [x] 입력받은 데이터 전달 | ||
|
|
||
| ### 출력 | ||
| - [x] 라운드 진행 시마다 경기 진행 상황 출력 | ||
| - [x] 경주 종료 후 최종 결과 및 우승자 출력 | ||
|
|
||
| ### 예외 처리 | ||
| - [x] 자동차 이름 관련 | ||
| - [x] 시도 횟수 관련 | ||
|
|
||
|
|
||
| ### 고민 사항 | ||
| - 자동차 정보를 입력받는 DTO를 어떻게 설계하는 것이 좋을까? | ||
| - 입력 텍스트 그대로(poni,woni,jun)를 DTO에 넣기 | ||
| - 이름을 분리하여 List<String>에 넣기 | ||
| - 이름을 분리한 것을 바탕으로 Car 객체들로 변환하고, List<Cars>에 넣기 | ||
| - Util 패키지 관련 | ||
| - 객체들을 new로 생성해서 사용하는 것이 좋은가? | ||
| - 아니면 객체를 별도로 생성하지 않고 객체 내부 메소드들을 모두 static 메소드로 만들어서 쓰는 것이 나은가? | ||
| - 시도 횟수를 입력할 때, 숫자가 아닌 다른 형태의 값을 입력했을 경우 | ||
| - CheckTryCount 라는 별도의 클래스에서 이를 검증할 방법은 없을까?(현재 코드는 sc.nextInt() 하는 시점에 try-catch를 통해 예외처리 하고 있음) |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,7 +1,16 @@ | ||
| package racingcar; | ||
|
|
||
| import racingcar.controller.RacingController; | ||
| import racingcar.controller.dto.RaceInfoResponse; | ||
| import racingcar.util.RaceManager; | ||
| import racingcar.view.InputView; | ||
| import racingcar.view.OutputView; | ||
|
|
||
| public class Application { | ||
| public static void main(String[] args) { | ||
| // TODO: 프로그램 구현 | ||
| RacingController racingController = new RacingController(new InputView(), new OutputView(), new RaceManager()); | ||
|
|
||
| RaceInfoResponse raceInfo = racingController.getInfosBeforeRaceStart(); | ||
| racingController.raceStart(raceInfo); | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,58 @@ | ||
| package racingcar.controller; | ||
|
|
||
| import racingcar.controller.dto.RaceInfoRequest; | ||
| import racingcar.controller.dto.RaceInfoResponse; | ||
| import racingcar.util.TryCountValidator; | ||
| import racingcar.util.RaceManager; | ||
| import racingcar.util.StringUtils; | ||
| import racingcar.model.Car; | ||
| import racingcar.view.InputView; | ||
| import racingcar.view.OutputView; | ||
|
|
||
| import java.util.List; | ||
|
|
||
| public class RacingController { | ||
| private final InputView inputView; | ||
| private final OutputView outputView; | ||
| private final RaceManager raceManager; | ||
|
|
||
| public RacingController(InputView inputView, OutputView outputView, RaceManager raceManager) { | ||
| this.inputView = inputView; | ||
| this.outputView = outputView; | ||
| this.raceManager = raceManager; | ||
| } | ||
|
|
||
| public RaceInfoResponse getInfosBeforeRaceStart() { | ||
| outputView.getCars(); | ||
| String racerStr = inputView.getStringInput(); | ||
|
|
||
| outputView.getTryCount(); | ||
| String tryCnt = inputView.getStringInput(); | ||
| TryCountValidator.checkTryCount(tryCnt); | ||
| int tryCount = Integer.parseInt(tryCnt); | ||
|
|
||
| RaceInfoRequest raceInfoInput = new RaceInfoRequest(racerStr, tryCount); | ||
|
|
||
| List<String> carNames = StringUtils.splitByComma(raceInfoInput.carNames()); | ||
|
|
||
| return new RaceInfoResponse(carNames, tryCount); | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. new로 객체를 생성하는 것도 좋지만
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 보고서에서 첨부해 주신 링크 잘 읽었습니다 |
||
| } | ||
|
|
||
| public void raceStart(RaceInfoResponse raceInfo) { | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 말씀해주신 대로 그런 부분들도 충분히 분리하여 코드 작성이 가능할 것 같습니다. |
||
| List<Car> cars = StringUtils.makeCarsUsingStrings(raceInfo.carNames()); | ||
|
|
||
| outputView.printRaceStart(); | ||
|
|
||
| for(int i = 0; i < raceInfo.gameCount(); ++i) { | ||
| raceManager.movingCars(cars); | ||
| outputView.printRaceStatus(cars); | ||
| } | ||
|
|
||
| finishRace(cars); | ||
| } | ||
|
|
||
| private void finishRace(List<Car> cars) { | ||
| List<String> winners = raceManager.findWinners(cars); | ||
| outputView.printRaceFinalStatus(winners); | ||
| } | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,7 @@ | ||
| package racingcar.controller.dto; | ||
|
|
||
| public record RaceInfoRequest( | ||
| String carNames, | ||
| int gameCount | ||
| ) { | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,9 @@ | ||
| package racingcar.controller.dto; | ||
|
|
||
| import java.util.List; | ||
|
|
||
| public record RaceInfoResponse( | ||
| List<String> carNames, | ||
| int gameCount | ||
| ) { | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,32 @@ | ||
| package racingcar.model; | ||
|
|
||
| import racingcar.util.CarNameValidator; | ||
|
|
||
| public class Car { | ||
| private static final int CAN_MOVE_STANDARD = 4; | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 우선 private는, 자동차가 움직이는 기준 값을 외부에 공개할 필요가 없기 때문에 private를 사용하였고, |
||
|
|
||
| private int location; | ||
| private String name; | ||
|
|
||
| public Car(String name) { | ||
| CarNameValidator.checkName(name); | ||
| this.name = name; | ||
| this.location = 0; | ||
| } | ||
|
|
||
| public void move() { | ||
| if(isAbleToMove()) ++location; | ||
| } | ||
|
|
||
| private boolean isAbleToMove() { | ||
| return (int)(Math.random() * 10) >= CAN_MOVE_STANDARD; | ||
| } | ||
|
|
||
| public int getLocation() { | ||
| return location; | ||
| } | ||
|
|
||
| public String getName() { | ||
| return name; | ||
| } | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,26 @@ | ||
| package racingcar.util; | ||
|
|
||
| public class CarNameValidator { | ||
| private static final int NAME_MAX_LENGTH = 5; | ||
|
|
||
| public static void isNull(String name) { | ||
| if(name == null) | ||
| throw new IllegalArgumentException("이름에는 null 값이 들어갈 수 없습니다."); | ||
| } | ||
|
|
||
| public static void isBlank(String name) { | ||
| if(name.isBlank()) | ||
| throw new IllegalArgumentException("이름은 공백일 수 없습니다."); | ||
| } | ||
|
|
||
| public static void isMoreThanMaxLength(String name) { | ||
| if(name.length() > NAME_MAX_LENGTH) | ||
| throw new IllegalArgumentException("이름은 5자를 넘을 수 없습니다."); | ||
|
Comment on lines
+7
to
+18
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 예외 발생 시 작성하는 메시지도 결국 매직 넘버라 상수화하거나 따로
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 이번 과제처럼 규모가 크지 않은 프로젝트에서는 Enum으로 분리해서 예외를 관리해도 괜찮겠다 생각했지만, There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 생각해보니 Enum에서 관리한다면 |
||
| } | ||
|
|
||
| public static void checkName(String name) { | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 비슷한 의미를 가지는 것처럼 보여도 디테일한 차이가 있었군요..! There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
|
||
| isNull(name); | ||
| isBlank(name); | ||
| isMoreThanMaxLength(name); | ||
| } | ||
| } | ||
| Original file line number | Diff line number | Diff line change | ||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -0,0 +1,20 @@ | ||||||||||||
| package racingcar.util; | ||||||||||||
|
|
||||||||||||
| import racingcar.model.Car; | ||||||||||||
|
|
||||||||||||
| import java.util.ArrayList; | ||||||||||||
| import java.util.List; | ||||||||||||
|
|
||||||||||||
| public class RaceManager { | ||||||||||||
| public void movingCars(List<Car> cars) { | ||||||||||||
| for(var c : cars) c.move(); | ||||||||||||
| } | ||||||||||||
|
|
||||||||||||
| public List<String> findWinners(List<Car> cars) { | ||||||||||||
| int maxLocation = cars.stream().mapToInt(Car::getLocation).max().orElse(0); | ||||||||||||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 메소드 체이닝은 주로 두 번째부터 줄바꿈을 사용해주고 있어요.
Suggested change
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 앗 참고하겠습니다.. |
||||||||||||
|
|
||||||||||||
| List<String> winners = cars.stream().filter(c -> c.getLocation() == maxLocation).map(Car::getName).toList(); | ||||||||||||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 여기도 마찬가지로 줄바꿈 적용해주세요! |
||||||||||||
|
|
||||||||||||
| return winners; | ||||||||||||
| } | ||||||||||||
| } | ||||||||||||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,20 @@ | ||
| package racingcar.util; | ||
|
|
||
| import racingcar.model.Car; | ||
|
|
||
| import java.util.Arrays; | ||
| import java.util.List; | ||
|
|
||
| public class StringUtils { | ||
| public static List<String> splitByComma(String str) { | ||
| return Arrays.stream(str.split(",")).toList(); | ||
| } | ||
|
|
||
| public static String NumToSticks(int count) { | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 여기 메소드 명이 파스칼 케이스로 적용되어 있어서 카멜 케이스로 변경해주세요! |
||
| return "-".repeat(count); | ||
| } | ||
|
|
||
| public static List<Car> makeCarsUsingStrings(List<String> strs) { | ||
| return strs.stream().map(Car::new).toList(); | ||
| } | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,21 @@ | ||
| package racingcar.util; | ||
|
|
||
| public class TryCountValidator { | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 보고서에서 언급해 주셨듯이, 말씀해주신 방법으로 일급 객체를 만든 다음 생성자 부분에서 유효성 검증을 옮기는 방법을 시도해 봐야겠습니다. |
||
| public static void isNumber(String tryCnt) { | ||
| try { | ||
| Integer.parseInt(tryCnt); | ||
| } catch (NumberFormatException e) { | ||
| throw new IllegalArgumentException("시도 횟수에 문자를 입력할 수 없습니다."); | ||
| } | ||
| } | ||
|
|
||
| public static void isPositive(int tryCnt) { | ||
| if(tryCnt < 0) | ||
| throw new IllegalArgumentException("시도 횟수는 자연수여야 합니다."); | ||
| } | ||
|
|
||
| public static void checkTryCount(String tryCnt) { | ||
| isNumber(tryCnt); | ||
| isPositive(Integer.parseInt(tryCnt)); | ||
| } | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,11 @@ | ||
| package racingcar.view; | ||
|
|
||
| import java.util.Scanner; | ||
|
|
||
| public class InputView { | ||
| private final Scanner sc = new Scanner(System.in); | ||
|
|
||
| public String getStringInput() { | ||
| return sc.nextLine(); | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,31 @@ | ||
| package racingcar.view; | ||
|
|
||
| import racingcar.util.StringUtils; | ||
| import racingcar.model.Car; | ||
|
|
||
| import java.util.List; | ||
|
|
||
| public class OutputView { | ||
| public void getCars() { | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 이 메소드 이름은 자동차 리스트를 가져오는? 의미로 볼 수 있을 것 같아요.
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 맞습니다 출력에 관련된 내용이니 get 보다는 print 가 어울릴 것 같습니다 수정하겠습니다! |
||
| System.out.println("경주할 자동차 이름을 입력하세요.(이름은 쉼표(,) 기준으로 구분)\n"); | ||
| } | ||
|
|
||
| public void getTryCount() { | ||
| System.out.println("시도할 회수는 몇회인가요?\n"); | ||
| } | ||
|
|
||
| public void printRaceStart() { | ||
| System.out.println("\n실행 결과"); | ||
| } | ||
|
|
||
| public void printRaceStatus(List<Car> cars) { | ||
| for(var c : cars) { | ||
| System.out.println(c.getName() + " : " + StringUtils.NumToSticks(c.getLocation())); | ||
| } | ||
| System.out.print('\n'); | ||
| } | ||
|
|
||
| public void printRaceFinalStatus(List<String> winners) { | ||
| System.out.print("최종 우승자 : " + String.join(", ", winners)); | ||
| } | ||
| } | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
RacingController에서 자동차 이름, 시도 횟수를 입력받는 메소드를 보시면 한 번에 두 입력을 받도록 하고 있어요. 이 부분은 분리가 가능하지 않을까요?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
네 맞습니다
보고서에도 작성했지만 이 부분을 분리한다면 아래 처럼 분리해보려고 하는데,
public String getCarNames() {
outputView.getCars();
String raceStr = inputView.getStringInput();
...
}
public String getTryCount() {
outputView.getTryCount();
String raceStr = inputView.getStringInput();
...
}
이렇게 한 다음 데이터를 처리하는 메소드를 아래 처럼 만들어서,
public RaceInfoResponse readyForRace(String carStrs, String tryCount) {
TryCountValidator.isPositive(tryCnt);
List carNames = StringUtils.splitByComma(carNames);
}
이렇게 작성하는 방식은 어떤가요??
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
좋은거 같아요!
그리고 입력 받는 메소드 명도
get~~대신 다른 단어로 바꿔보는 것도 좋을 것 같아요