-
Notifications
You must be signed in to change notification settings - Fork 446
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
[1단계 - 자동차 경주] BE_필즈(조성우) 미션 제출합니다 #331
Changes from 42 commits
217eb90
f8be399
ae87754
94698e6
e557cbc
7c5e0b5
97c1b8c
a772221
a84b13a
b628764
733265b
fd25aae
0cddf9c
803addf
81d6511
cee8a63
7103816
3cdcae9
cd13c29
71e2ec0
b2981b4
1221a56
5c48862
d275f38
4df38f5
9eb188f
806b28e
11cc2ba
e7e1b15
853d418
21693a8
7d98cb3
ba247d1
e962c14
83a5a83
fd36fb6
083c2ce
2f00f06
92c79cd
4e392ec
13d34d6
6012ceb
d1a6375
55e3506
d68246b
3c367fd
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,83 @@ | ||
|
||
|
||
# 첫 번째 Pull Request | ||
|
||
--- | ||
|
||
안녕하세요 ! 잘 부탁드립니다 ㅎㅎ 필즈(Philz)입니다 ! | ||
|
||
이렇게 공식적으로 코드리뷰를 받아보는 것은 처음인데.. 두근두근! 합니다 ㅎㅎ :) | ||
|
||
리뷰를 받을때 궁금한 사항들이 생겨.. 몇가지 질문을 같이 드리고자 합니다 ㅠ | ||
(너무 많으면 생략하셔도 됩니다 ㅠ ㅎㅎ..) | ||
|
||
--- | ||
|
||
### 1. 앵귤러 커밋 컨벤션에서.. 스코프 | ||
|
||
--- | ||
|
||
![image](https://user-images.githubusercontent.com/66164361/153561334-1f6cc7ef-62b6-41f5-b5d2-5cc653eebbbe.png) | ||
|
||
|
||
커밋 메시지를 적을 때 `feat(스코프)` 라고 적는데 이 스코프에는 어떤 내용이 들어가는지 확신이 서지 않습니다 . domain이란 개념으로 받아들여도 될까요? | ||
> 예) feat(Item): 구조 수정 | ||
|
||
### 2-1.`패키지구조` domain 클래스 안에 패키지가 여러개 있어도 되나요? | ||
|
||
--- | ||
|
||
예를들어 자동차의 움직임을 묘사하는 strategy 패턴 같은 곳을 정의 하는 패키지가 이곳에 오는 지 궁금합니다 | ||
|
||
### 2-2. `패키지 구조` domain 과 controller, service 등이 있을때 어떻게 나뉘는지 궁금합니다 | ||
|
||
--- | ||
|
||
> 아래에서 domain 은 station, line 입니다! | ||
|
||
1. | ||
![image](https://user-images.githubusercontent.com/66164361/153560471-29b9e4bb-44bf-467d-a313-a1bc50661077.png) | ||
|
||
2. | ||
![image](https://user-images.githubusercontent.com/66164361/153560504-aa3b36c7-e333-4401-a9cc-95a4ef8cc11d.png) | ||
|
||
### 3. 실무에서 반드시 자바 빈 프로퍼티 규약을 준수 하나요?? | ||
|
||
--- | ||
|
||
제 코드에서 Car는 별도로 CarName 값 객체를 멤버로 두었습니다. | ||
Car객체에서 이름을 반환하고자 할때는 `car.getName()` 을 사용하지만 | ||
CarName 에서까지 getter를 사용하면, **name.getName()** 이 되어서 의미상 중복(`name`)이 되기에 | ||
`name.get()` 으로 시그니쳐를 정하려고 하는데 실무에서는 어떤지 궁금합니다 | ||
|
||
|
||
### 4. 테스트 코드 작성시 `public` 으로 노출하고 싶지 않았던 메서드를 테스트하게 될 때 | ||
|
||
--- | ||
|
||
예전에 혼자서 테스트 코드를 작성할 때 한 번 써보았던 방법인데 | ||
|
||
외부로 최대한 노출 안시키고자 하는 타협점에서 (그렇다고 리플렉션까지는 가지 않기 위해..) 사용해보았던건데.. | ||
|
||
`CarTest extends Car` 로 상속받은 후에 | ||
|
||
`protected` 를 써서 테스트 코드를 한 번 작성해본 적이 있었습니다 | ||
|
||
이경우 단점으로는 **결국 메서드 시그니쳐가 변경**되지만 | ||
|
||
장점으로 **그래도 완전히 외부로 노출되지는 않음** 이 된다고 생각했었는데.. 실무에서는 주로 어떻게 접근하는지 궁금합니다 | ||
|
||
|
||
|
||
### 5. 실무에서도 값 객체를 많이 활용하나요?? | ||
|
||
--- | ||
|
||
넥스트 스텝, 우테코를 통해서 VO라는 개념이 엔티티와는 다르단 것을 알았습니다 ! | ||
|
||
Car에는 CarName이 있는 것 처럼 실무에서도 값 객체를 통한 검증로직 등을 내부로 감싸서 해결하는 등의 방식을 많이 사용하고 있는지 궁금합니다.. ㅎㅎ.. | ||
|
||
|
||
#### 이상입니다 ! 읽어주셔서 감사해요 ㅠ | ||
|
||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,7 +1,68 @@ | ||
# java-racingcar | ||
# 문자열 덧셈 계산기 | ||
|
||
자동차 경주 미션 저장소 | ||
--- | ||
|
||
## 우아한테크코스 코드리뷰 | ||
## 기능 구현 목록 | ||
|
||
- [온라인 코드 리뷰 과정](https://github.com/woowacourse/woowacourse-docs/blob/master/maincourse/README.md) | ||
- 쉼표 `,` 혹은 콜론 `:` 을 구분자로 하는 각 숫자의 합 반환 | ||
|
||
> 예시 | ||
|
||
| 입력 | 출력 | | ||
| ------- | ---- | | ||
| "" | 0 | | ||
| "1,2,3" | 6 | | ||
| “1,2:3” | 6 | | ||
|
||
- [x] 커스텀 구분자 | ||
- `//` 와 `\n` 사이의 문자가 사용자가 지정한 구분자가 된다 | ||
|
||
> 예시 | ||
|
||
| 입력 | 출력 | | ||
| ------------ | ---- | | ||
| `//;\n1;2;3` | 6 | | ||
|
||
## 예외 처리 목록 | ||
|
||
- [x] `RuntimeException` 으로 처리할 것 | ||
- [x] 숫자이면서 음수 | ||
- [x] 숫자가 아닌 것 | ||
- 한글 | ||
- 영어 | ||
- 특수문자 | ||
- 공백(스페이스, 탭, \n, \r 등) | ||
|
||
# 자동차 경주 미션 | ||
|
||
--- | ||
|
||
## 기능 구현 목록 | ||
|
||
- [x] 주어진 횟수 동안 n대의 자동차는 전진 혹은 멈출 수 있다 | ||
- 즉 하나의 자동차는 턴마다 멈추거나 전진한다 | ||
- [x] 자동차에는 이름이 있다 | ||
- 자동차 출력시에 이름이 표시된다 | ||
- [x] 자동차의 이름은 쉼표를 기준으로 구분한다 | ||
- 이름은 5자만 가능 | ||
- [x] 사용자는 완주 이동 횟수를 입력한다 | ||
- [x] 0 ~ 9 의 random 값을 구한 후 | ||
- 0 ~ 3 멈춤 | ||
- 4 ~ 9 전진 | ||
- [x] 우승자를 판별한다 | ||
- 우승자는 2명이상 일 수 있다 | ||
|
||
## 예외 처리 목록 | ||
|
||
- [x] 자동차의 이름에는 한글, 영어, 숫자, 언더바만 올 수 있다 | ||
- 특수문자나 `null`은 허용하지 않는다 | ||
- [ ] 완주 이동횟수는 숫자만 입력 가능하다 | ||
- 음수를 입력할 수 없다 | ||
- 0도 허용하지 않는다 | ||
- [ ] 현재 식별자는 이름밖에 없으므로 자동차 선수들이 여러명일 때 중복된 이름을 허용하지 않는다 | ||
- > 리뷰어 `heebong`님의 예외사항 아이디어 ! | ||
hint : `Set` | ||
|
||
## 기술 관련 사항 목록 | ||
- [ ] Random과 ThreadLocalRandom 차이를 익히고 적재적소 적용 | ||
- > `heebong`님 아이디어! |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
package racingcar; | ||
|
||
import racingcar.controller.CarController; | ||
import racingcar.repository.CarRepository; | ||
import racingcar.view.InputView; | ||
|
||
public class RacingCarApplication { | ||
|
||
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. 체크 완료 ! |
||
private static CarController carController; | ||
private static CarRepository carRepository; | ||
private static InputView inputView; | ||
|
||
public static void main(String[] args) { | ||
|
||
injectDependency(); | ||
playGame(); | ||
} | ||
|
||
private static void playGame() { | ||
carController.initGame(); | ||
carController.playGame(); | ||
carController.showWinners(); | ||
carController.end(); | ||
} | ||
|
||
private static void injectDependency() { | ||
inputView = new InputView(); | ||
carRepository = new CarRepository(); | ||
carController = new CarController(carRepository, inputView); | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,98 @@ | ||
package racingcar.controller; | ||
|
||
import java.util.List; | ||
|
||
import racingcar.controller.dto.CarDto; | ||
import racingcar.domain.Car; | ||
import racingcar.domain.Cars; | ||
import racingcar.domain.vo.TryRoundNumber; | ||
import racingcar.repository.CarRepository; | ||
import racingcar.util.Voider; | ||
import racingcar.view.InputView; | ||
import racingcar.view.OutputView; | ||
|
||
public class CarController { | ||
|
||
private final CarRepository carRepository; | ||
private final InputView inputView; | ||
|
||
private int roundNumber; | ||
|
||
public CarController(CarRepository carRepository, InputView inputView) { | ||
this.carRepository = carRepository; | ||
this.inputView = inputView; | ||
} | ||
|
||
public void initGame() { | ||
initCars(); | ||
initRoundNumbers(); | ||
} | ||
|
||
private void initCars() { | ||
Voider voider = () -> { | ||
String carNames = inputView.inputCarNames(); | ||
Cars cars = new Cars(carNames); | ||
List<Car> carList = cars.getCars(); | ||
carRepository.addCars(carList); | ||
}; | ||
commonInputProcess(voider); | ||
} | ||
|
||
private void initRoundNumbers() { | ||
Voider voider = () -> { | ||
String input = inputView.inputRoundNumber(); | ||
TryRoundNumber tryRoundNumber = new TryRoundNumber(input); | ||
roundNumber = tryRoundNumber.get(); | ||
}; | ||
commonInputProcess(voider); | ||
} | ||
|
||
private void commonInputProcess(final Voider inputFunction) { | ||
while (true) { | ||
try { | ||
inputFunction.execute(); | ||
return; | ||
} catch (Exception exception) { | ||
inputView.printErrorMessage(exception); | ||
} | ||
} | ||
} | ||
|
||
public void playGame() { | ||
OutputView.printResultMessage(); | ||
for (int i = 0; i < roundNumber; i++) { | ||
playRound(); | ||
} | ||
} | ||
|
||
public void playRound() { | ||
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. 체크 완료 감사합니다 ! |
||
List<Car> cars = carRepository.findAll(); | ||
moveCars(cars); | ||
List<CarDto> carDtos = CarDto.from(cars); | ||
OutputView.showCurrentStatus(carDtos); | ||
} | ||
|
||
public List<Car> getWinners() { | ||
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. 맞아요 테스트 코드 떄문에 default로 해 놓았었던건데... 흠 이부분은 한번 고민해봐야겠네요 |
||
List<Car> findCars = carRepository.findAll(); | ||
|
||
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. 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. 맞습니다 !! 저게 |
||
Cars cars = new Cars(findCars); | ||
|
||
return cars.getWinners(); | ||
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. 아 ㅎㅎ 일급컬렉션에게 위임한건데 알아봐 주셨군요 ㅎ 이런이런..훗 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 moveCars(List<Car> cars) { | ||
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. ㅎㅎ 여기 |
||
for (Car car : cars) { | ||
car.move(); | ||
} | ||
} | ||
|
||
public void end() { | ||
inputView.terminateScanner(); | ||
} | ||
|
||
public void showWinners() { | ||
List<Car> winners = getWinners(); | ||
List<CarDto> carDtos = CarDto.from(winners); | ||
OutputView.showGameResult(carDtos); | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,48 @@ | ||
package racingcar.controller.dto; | ||
|
||
import java.util.ArrayList; | ||
import java.util.List; | ||
import java.util.function.Function; | ||
|
||
import racingcar.domain.Car; | ||
import racingcar.domain.vo.CarName; | ||
|
||
public class CarDto { | ||
|
||
private final CarName name; | ||
private final int position; | ||
|
||
public CarDto(CarName name, int position) { | ||
this.name = name; | ||
this.position = position; | ||
} | ||
|
||
public String getName() { | ||
return name.get(); | ||
} | ||
|
||
public int comparePositionTo(final CarDto other) { | ||
return compareTo((CarDto otherCar) -> this.position - otherCar.position, other); | ||
} | ||
|
||
public int compareNameTo(final CarDto other) { | ||
return compareTo((CarDto otherCar) -> this.name.get().compareTo(other.getName()), other); | ||
} | ||
|
||
public int compareTo(final Function<CarDto, Integer> function, final CarDto other) { | ||
return function.apply(other); | ||
} | ||
|
||
public static List<CarDto> from(List<Car> cars) { | ||
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. 아.. ㅎㅎ DTO 클래스 제거 전의
음 생각해보니 car의 생성을 CarDto 클래스에 위임하는 방법도 있긴한데.. 닭이 먼저냐, 달걀이 먼저냐 하는 느낌이 있어서 ㅎㅎ.. |
||
List<CarDto> carDtos = new ArrayList<>(); | ||
for (Car car : cars) { | ||
carDtos.add(car.toDto()); | ||
} | ||
return carDtos; | ||
} | ||
|
||
@Override | ||
public String toString() { | ||
return name + " : " + "-".repeat(position); | ||
} | ||
} |
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.
2. 기억하기 위한 마크다운 파일
도 답변 드릴게요 😄질문 기록을 위한 마크다운 파일 💯 아아주 훌륭합니다! 필즈가 기억하고 정리하는데 좋다면 무엇이 문제일까요!
최상위 문서로 만들어도 괜찮고, 정 그러면 최상위에
study
혹은question
같은 폴더를 만들고 그 안에 md 파일을 올려도 괜찮을 것 같아요 👍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.
아 !! ㅎㅎㅎ 감사합니다.. 칭찬 너무 잘해주시는거 같아요, 넘 기쁘네요 ㅎㅎㅎ