Skip to content

[미션1] 구현 완료했습니다. 리뷰 요청드립니다.#7

Open
sunghyuki wants to merge 5 commits intosproutt:kikatfrom
sunghyuki:step1
Open

[미션1] 구현 완료했습니다. 리뷰 요청드립니다.#7
sunghyuki wants to merge 5 commits intosproutt:kikatfrom
sunghyuki:step1

Conversation

@sunghyuki
Copy link
Collaborator

@sunghyuki sunghyuki commented Aug 19, 2020

description :
•어려웠던 점
객체 지향 프로그래밍이 익숙하지 않아서 객체가 하는 일을 규정하고, 한 객체가 어떤 책임을 갖고 다른 객체들과 협력해야 하는지 로직을 디자인하는데 있어서 시간이 많이 걸렸던 것 같다.
캡슐 내의 요소들에 대한 세부 구현 사항을 외부로부터 숨기는 객체 지향의 관점에서 프로그래밍을 하는 능력이 부족한 것 같아서 자료를 많이 찾아보고 공부하고 있는 중이다.
한 메서드에 오직 한 단계의 들여쓰기만 해야 하는 규칙을 지키기가 어려웠던 것 같다.

Copy link
Contributor

@hyukjin-lee hyukjin-lee left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

고생하셨습니다 ~
열심히 고민하신 흔적이 보이네요 !
피드백 조금 남겼으니 확인 후 반영해주시면 감사하겠습니다

src/Car.java Outdated
return position;
}

public void setPosition(int position) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

규칙 : setter 를 사용하지 않는다 (getter 사용은 지양한다)

객체지향 프로그래밍에서 setter 와 getter 사용을 되도록 지양하라고 하는 이유가 무엇일까요?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

불필요한 setter/getter는 객체의 속성을 언제든 변경할 수 있는 상태가 되기 때문에 지양하도록 하는 것 같습니다! 굳이 사용하지 않아도 된다면 반영해보도록 하겠습니다!

if(random.nextInt(10) >= 4){
this.setPosition(this.getPosition()+1);
}
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

랜덤을 통해 특정 조건에서 전진하는 게임의 룰을 자동차라는 모델 클래스가 알고 있을 필요가 있을까요?
예를 들어 게임의 모드가 추가되어서 랜덤 룰이 아닌 다른 게임 룰이 생긴다고 했을 때,
모델이 게임의 룰에 관계없이 pure 하게 짜여져 있으면 모델을 수정하지 않아도 되지 않을까요?
moveForward 가 단순히 car 의 position 을 ++ 하는 로직만 가지고 있으면 어떤지 의견드려봅니다 ~

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

게임의 룰을 자동차 모델 클래스가 가지고 있을 필요는 없다고 생각했는데 보다 더 좋은 방법을 아직 생각해보지 못한 것 같습니다. 원래는 Rule 클래스를 따로 만들어 구현하려고 했으나 아직 방법을 고민 중에 있습니다! 고민해서 반영할 수 있도록 노력해보겠습니다

src/Car.java Outdated
public void goForward(){
Random random = new Random();
if(random.nextInt(10) >= 4){
this.setPosition(this.getPosition()+1);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

다음에는 code formatting 을 한 뒤에 제출하는 습관을 들이시면 좋을 것 같아요 ~ :)

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

넵 code formatting 하는 습관을 들이겠습니다!

src/Car.java Outdated

public void goForward(){
Random random = new Random();
if(random.nextInt(10) >= 4){
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

10, 4 가 어떤 의미를 지니고 있는지 2년 뒤에 이 코드를 보거나 타인이 보면 이해가 잘 안될 수 있을 것 같아요.
이런 magic number 를 상수로 추출해보는게 어떨까요?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

magic number 역시 추후에 봤을 때 이해할 수 있도록 상수로 선언하는 습관을 들이겠습니다!

import java.util.Scanner;

public class InputView {
private static final Integer MAX_LENGTH = 6;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

primitive type 이 아니라 wrapper type 으로 선언하신 이유가 있을까요?

src/Race.java Outdated
import java.util.stream.Collectors;

public class Race {
final static String drive = "-";
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

접근 제어자가 생략되었네요.
앞의 클래스에서는 static final 로 쓰셨던데 통일해보면 어떨까요?
상수의 네이밍 컨벤션은 ALL_대문자 입니다 ~

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

메모하겠습니다!

src/Race.java Outdated

public class Race {
final static String drive = "-";
private List<Car> carLineUp = new ArrayList<>();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

cars 라는 네이밍이 좋을 것 같아요

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

초기화를 생성자를 통해 하지 않고 필드에서 직접 해주는 이유가 있나요?

src/Race.java Outdated
private List<Car> carLineUp = new ArrayList<>();
private int trial;
InputView inputView = new InputView();
OutputView outputView = new OutputView();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Race 라는 도메인 클래스에서 View 에 대한 의존성을 없애면 어떨까요?
나중에 요구사항이 늘어나서 View 가 변경되면 그에 따라 Race 클래스가 영향을 받게 되는데
여기서 View 에 대한 책임을 Main(RacingGame) 으로 위임하면 추후에 view 에 변경이 생겨도
도메인 클래스들에는 영향이 최소화 되지 않을까요~?

@@ -0,0 +1,8 @@
public class RacingGame {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

전체적으로 테스트 코드가 없어서 아쉽네요 ㅠㅠ

Copy link
Contributor

@hyukjin-lee hyukjin-lee left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

고생하셨습니다~
추가 피드백 남겼으니 확인 부탁드려요~


private static void processStreamAboutCheckName(String[] trimmedInputCarName) {
Stream<String> stream = Arrays.stream(trimmedInputCarName);
stream.forEach(e -> checkNameLength(e));
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

메서드 체이닝을 적용해서 Arrays.stream(trimmedInputCarName).forEach(~~)
로 이어 붙이시면 어떨까요

src/Race.java Outdated

public void race(List<Car> cars) {
for(Car car: cars) {
goOrStay(car);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

레이스에 참여하는 cars 의 정보를 직접 Race 가 들고 있으면 어떨까요?
getWinner 부터 race 까지
메서드를 사용함에 있어서 객체가 상태를 들고 있지 않기 때문에
응집도가 떨어지고 사용하는 쪽의 클래스와 결합도가 커지는 것 같습니다.

src/Race.java Outdated
import java.util.stream.Collectors;

public class Race {
Rule rule = new Rule();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

접근제어자 표기를 안하신 이유가 있을까요?
Rule 객체는 상태가 없는 객체인데 util 클래스 목적으로 추출하신걸까요?
util 목적으로 사용하실 클래스라면, Race 객체가 생성될 때마다 함께 생성될 필요가 있을까요?

src/Race.java Outdated
public List<String> getWinner(List<Car> cars) {
List<Car> winner = new ArrayList<>();
int positionOfWinner;
positionOfWinner = findPositionOfWinner(cars);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

선언과 할당을 같은 곳에서 해주면 가독성에 좀 더 유리할 것 같습니다

src/Race.java Outdated
}

public List<String> getWinner(List<Car> cars) {
List<Car> winner = new ArrayList<>();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

여기서 객체 할당을 해주는 것은 의미없는 메모리 낭비일 것 같습니다.
(stream 연산을 통해 변형된 cars 를 할당받고 있기 때문에)

import static org.hamcrest.CoreMatchers.is;
import static org.junit.Assert.assertThat;

public class RacingGameTest {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

view 를 제외한 모든 클래스에 대해 테스트를 진행해보시면 어떨까요?

}

@Test
public void inputCarName() throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

reflection 을 사용하지 않고 테스트를 구현해보시면 어떨까요?

관련해서 도움이 될 만한 자료 첨부드립니다
blog.benelog.net/2685835.html

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants