Skip to content

[2단계 - 자동차 경주 리팩터링] 기론(김규철) 미션 제출합니다. #362

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

Merged
merged 6 commits into from
Feb 18, 2022

Conversation

Gyuchool
Copy link

안녕하세요 제이!
다시 뵙게 되어서 반갑습니당😀 이번 미션도 잘 부탁드리겠습니다.

MVC 리펙토링

mvc패턴에서는 controller에서 view를 통해 받아야 하므로 Application을 통해 받던 InputView, OutputView를 RacingGame 컨트롤러를 통해서 받도록 리펙토링했습니다!

궁금했던 점

private 매서드를 테스트 하는 방법을 찾는 중, 제가 테스트 코드에 작성했던것처럼 racingGameClass.getClass().getDeclaredMethod("getWinnersName"); 와 같은 매서드를 사용할 수 있더군요.
사실 이전에는 private 매서드는 믿고 간다고 생각한다고 들었던 적이 있어서 따로 테스트를 안해왔었습니다.

이번에 이러한 방식을 알고 사용하려는데, 혹시 위 메서드를 사용하는 방식에 대해 단점이 있을까요? 이번에 공부하면서 찾은 이 방법을 지금까지 저는 주변에서는 본 적이 없어서 혹시 어떤 큰 단점이 있어서 안 사용하는 것인지 아니면 사용은 하는데 제가 이제서야 알게된 것인지 궁금합니다!

제 생각에는 디미터의 법칙을 어기는 것과 매서드 이름이 바뀔때마다 getDeclaredMethod매서드의 인자를 바꿔야 한다는 점이 단점이지만 쉽게 private 매서드도 검증할 수 있어서 좀 더 완전한 테스트가 될 수 있지 않을까 하고 생각하면서 사용하였습니다.

감사합니다!🙏

Copy link

@JunHoPark93 JunHoPark93 left a comment

Choose a reason for hiding this comment

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

안녕하세요 기론!
2단계 미션하느라 고생많으셨습니다.
변경된 코드의 양은 많지는 않네요! private method테스트 관련해서 남겨주셨는데 구조를 한번 바꿔보면 문제를 해결할 수 있을것으로보여요.
코멘트 확인해보시고 궁금한점 있다면 다시 남겨주세요~

Comment on lines 75 to 81
RacingGame racingGameClass = new RacingGame(racingCars);

Method getWinnersName = racingGameClass.getClass().getDeclaredMethod("getWinnersName");
getWinnersName.setAccessible(true);

String actual = (String) getWinnersName.invoke(racingGameClass);

Choose a reason for hiding this comment

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

질문주신 내용입니다.

private 매서드를 테스트 하는 방법을 찾는 중, 제가 테스트 코드에 작성했던것처럼 racingGameClass.getClass().getDeclaredMethod("getWinnersName"); 와 같은 매서드를 사용할 수 있더군요.
사실 이전에는 private 매서드는 믿고 간다고 생각한다고 들었던 적이 있어서 따로 테스트를 안해왔었습니다.
이번에 이러한 방식을 알고 사용하려는데, 혹시 위 메서드를 사용하는 방식에 대해 단점이 있을까요? 이번에 공부하면서 찾은 이 방법을 지금까지 저는 주변에서는 본 적이 없어서 혹시 어떤 큰 단점이 있어서 안 사용하는 것인지 아니면 사용은 하는데 제가 이제서야 알게된 것인지 궁금합니다!
제 생각에는 디미터의 법칙을 어기는 것과 매서드 이름이 바뀔때마다 getDeclaredMethod매서드의 인자를 바꿔야 한다는 점이 단점이지만 쉽게 private 매서드도 검증할 수 있어서 좀 더 완전한 테스트가 될 수 있지 않을까 하고 생각하면서 사용하였습니다.

private 메서드를 테스트를 해야되는지부터 고민을 다시 해보면 좋을 것 같아요.
흐름상 winner를 구해서 테스트를 해본다 라는것은 필요한 테스트로 보입니다.
현재 구조에서 winner를 테스트하는방법이 private method를 강제로 접근하게 하여 테스트를 해야되는 방법밖에 없다면 구조를 개선해보면 좋은 신호라고 생각해요.
어떻게 개선하면 좋을까요? 🤔

Choose a reason for hiding this comment

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

힌트를 드리자면 winner를 구하는 책임은 현재 만들어주신 클래스 중에서 domain패키지안에 둘 중에 한 클래스가 가지게 하면 될 것 같아요. 그렇다면 우승자를 구하는 테스트는 해당 도메인 테스트로 만들 수 있겠네요 :)

Copy link
Author

Choose a reason for hiding this comment

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

처음에 Game이 진행되는 컨트롤러 안에서 우승자를 결정해야 한다고 생각헀는데, 제이의 리뷰를 받고 car들을 관리하는 RacingCars 도메인에서 우승자를 결정하니 복잡하던 테스트 코드들도 깔끔해졌고 도메인 테스트 코드를 짤때 컨트롤러에 의존하지 않아도 되어서 작성하기 더욱 편리했습니다.

또한 private 매서드를 테스트를 해야되는지부터 고민해보는 게 좋다는 말씀에서 현재 구조가 잘 짜여졌는지 다시 한번 생각해볼 수 있었던 거 같아요!

Copy link

@JunHoPark93 JunHoPark93 left a comment

Choose a reason for hiding this comment

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

안녕하세요 기론!
피드백 반영 하시느라 고생많으셨어요!
이번 미션에서 꼭 경험하고 가야할 내용이 아직 남아있어서 한번 더 요청을 드려요.
확인주시고 반영 부탁드릴게요~

public RacingCar getRacingCarWithMaxPosition() {

public String getWinnersName() {
ArrayList<RacingCar> winners = getWinners();

Choose a reason for hiding this comment

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

구체타입이 아닌 인터페이스로 선언하면 어떤 장점이 있을까요? 🤔
추후 미션을 진행하시면서 고민해보시면 좋을 것 같아요.

Copy link
Author

@Gyuchool Gyuchool Feb 17, 2022

Choose a reason for hiding this comment

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

제가 알기로는 인터페이스를 사용하면 결합도를 낮출 수 있고 재사용성이 증가하는 것이 장점이라고 알고 있습니다. 또한 제이가 저번 리뷰때 말씀해주신 것처럼 랜덤 값 테스트할때 인터페이스를 사용하면 효율적으로 테스트가 가능하다고 배웠습니다.
출처: https://tecoble.techcourse.co.kr/post/2020-05-17-appropriate_method_for_test_by_interface/

그런데 이러한 장점은 알겠는데 언제 인터페이스를 사용하여 구현해야 할지 잘 모르겠습니다. 제가 생각하기엔 모든 클래스마다 인터페이스를 만들어서 사용하기엔 과하다 싶은 생각이 드는데, 인터페이스를 적용하기 좋은 상황(?)이 있을까요?
그리고 테스트를 위한 매서드를 생성하는 것에 대해서 제이는 어떻게 생각하시는지 궁금합니다!

Copy link

@JunHoPark93 JunHoPark93 Feb 18, 2022

Choose a reason for hiding this comment

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

넵 당연히 모든 클래스마다 인터페이스를 만들라는 의미는 아닙니다.
ArrayList같은 경우는 우리가 만든 클래스가 아닌 기본적으로 자바에서 사용할 수 있는 클래스고 List라는 인터페이스를 제공하기 때문에 말씀드린거였어요.
적용하기 좋은 상황이라면 이미 말씀을 잘 주셨네요 :)

그리고 테스트를 위한 매서드를 생성하는 것에 대해서 제이는 어떻게 생각하시는지 궁금합니다!

이거는 다른 주제의 질문인거같아요!
테스트를 위한 메서드를 만드는것은 개인적으로 지양하고있습니다. 단순히 생각하면 실제 프로덕션 코드에서 쓰이지 않기 때문이에요.
저는 테스트를 위한 메서드가 필요하다고 생각이 들때는 구조를 잘못짠게 아닌가 스스로 반문하고있어요.

for (RacingCar winner : winners) {
winnersName.add(winner.getName());
}
return String.join(WINNER_NAME_DELIMITER, winnersName);

Choose a reason for hiding this comment

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

여기도 view에 의존적인 코드가 아직 남아있는것으로 보여요.
자동차의 리스트만을 넘겨주고 이름을 쉼표로 붙여주는 과정은 view에 책임을 주는게 어떨까요?

💡 MVC 구조에 맞는 객체분리

Comment on lines 46 to 50
for (RacingCar racingCar : racingCars) {
if (racingCar.isSamePosition(racingCarOfMaxPosition)) {
winners.add(racingCar);
}
}

Choose a reason for hiding this comment

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

depth를 1로 줄이려면 어떻게 해야할까요? 🤔

💡 규칙 1: 한 메서드에 오직 한 단계의 들여쓰기만 한다.

Copy link

@JunHoPark93 JunHoPark93 left a comment

Choose a reason for hiding this comment

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

안녕하세요 기론!
리뷰 반영 잘 해주셨네요 👍
질문 주신 부분은 코멘트 달아두었어요!
첫 미션이 끝났네요! 😃
남은 우테코 기간에는 단기간에 무리하지않고, 성공적으로 완주하시길 바랍니다 🙏

@JunHoPark93 JunHoPark93 merged commit c3fa3cb into woowacourse:gyuchool Feb 18, 2022
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