Skip to content
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

[톰캣 구현하기 - 3, 4단계] 아코(안석환) 미션 제출합니다. #466

Merged
merged 12 commits into from
Sep 14, 2023

Conversation

seokhwan-an
Copy link

@seokhwan-an seokhwan-an commented Sep 11, 2023

안녕하세요 망고!

1, 2단계가 마무리 되고 3, 4단계를 진행하면서 리팩토링과 동시성 처리 및 스레드 확장을 적용했습니다.
리팩토링 과정에서 Controller가 생긴 만큼 Controller에 대한 테스트를 진행했습니다.

이번 미션을 진행하면서 고민이 되었던 점이 있었는데요!
동시성 관련 기능들을 추가했지만 이를 테스트를 해야할 방법에 대해서 알지 못해서 부득이 하게 이 부분은 테스트를 작성하지 못했습니다.(아예 감이 잡히지 않습니다 ㅜㅜ) 망고는 이 부분을 어떻게 해결하셨나요? 이 부분에 대한 망고의 조언이 듣고 싶습니다.

이번 리뷰도 잘 부탁드립니다!🙇‍♂️

세부사항
- controller 도입하기
- 파일 읽어오는 기능 util 클래스로 분리하기
세부사항
- sessionManager에 동시성 컬렉션 적용
- Executors로 Thread Pool 적용
Copy link

@Go-Jaecheol Go-Jaecheol left a comment

Choose a reason for hiding this comment

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

안녕하세요 아코!
3, 4단계도 고생하셨어요 😎

리팩터링 하면서 전체적으로 코드도 깔끔해졌고, 지나가면서 했던 만족스럽단 말이 뭔지 알 것 같네요 👍

가볍게 생각해볼만한 질문들과 피드백 몇 가지 남겨놓았습니다!
(쓰레드랑 동시성 관련 테스트는 같이 고민해보아요..)

마지막까지 화이팅~~!!~!

Comment on lines 22 to 25
if (REQUEST_MAPPER.containsKey(path)) {
return REQUEST_MAPPER.get(path);
}
return new PageController();

Choose a reason for hiding this comment

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

Suggested change
if (REQUEST_MAPPER.containsKey(path)) {
return REQUEST_MAPPER.get(path);
}
return new PageController();
return REQUEST_MAPPER.getOrDefault(path, new PageController());

이 부분은 취향 차이라고 생각하는데
getOrDefault를 사용해서 라인을 줄일 수 있어요!

Copy link
Author

Choose a reason for hiding this comment

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

엄청 깔끔하네요! 배워갑니다 저도 if문이 없는 부분이 더 가독성이 좋은 것 같습니다👍👍

Comment on lines 11 to 13
private static final String CONTENT_TYPE = "Content-Type";
private static final String CHARSET_UTF_8 = ";charset=utf-8";
private static final String CONTENT_LENGTH = "Content-Length";

Choose a reason for hiding this comment

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

AbstractController를 상속하는 Controller 클래스에서 중복해서 사용하는 상수들(CONTENT_TYPE, CONTENT_LENGTH, LOCATION 등)은 상위 추상 클래스에 protected로 선언한 후 사용하면서 중복을 없애는 건 어떻게 생각하시나요??

Copy link
Author

Choose a reason for hiding this comment

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

저도 중복되는 것은 protected로 처리되는 것이 반복되는 요소를 줄일 수 있어서 좋을 것 같습니다!☺️

Comment on lines -16 to +15
private HttpRequest(
public HttpRequest(

Choose a reason for hiding this comment

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

HttpRequest, QueryString, RequestBody 클래스에서 기본 생성자를 private에서 public으로 다시 열어준 이유가 있을까요??
위 클래스들에서 전부 정적 팩터리 메서드를 사용하고 있는 걸로 보이는데, 이 때 정적 팩터리 메서드와 생성자에 대해 아코만의 기준이 있다면 들어보고 싶어요!

Copy link
Author

Choose a reason for hiding this comment

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

저도 기본적으로 정적팩토리 메소드를 이용할 때에는 생성자를 private로 합니다. 제가 이번에 생성자를 public으로 둔 이유는 각 controller 테스트의 given의 편의성을 높이기 위해서 였습니다. 그래서 생성자를 통해 HttpRequest를 생성해서 테스트를 진행했습니다. 이처럼 저는 테스트의 편의성을 위해 정적펙토리 메소드가 있음에도 생성자를 Private에서 public으로 접근제어자를 변경했는데 이 부분에 대해서 망고는 어떻게 생각하시나요?

Choose a reason for hiding this comment

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

저는 개인적으로 테스트를 위한 프로덕션 코드 수정을 안좋아하는 편이어서 private으로 두긴 했어요ㅎ
이것도 편의성이냐 안정성이냐 어느 부분을 중요하게 여기느냐에 따라 사람마다 다를 것 같네요 😎

Comment on lines 8 to 10
StatusCode statusCode;
HttpHeader httpHeader;
String body;

Choose a reason for hiding this comment

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

HttpResponse 클래스에서는 default 접근 제어자를 사용한 이유가 있을까요??

Copy link
Author

Choose a reason for hiding this comment

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

아 부끄럽네요.. 이 부분 빠르게 수정하겠습니다.

Comment on lines 23 to 27
if (request.hasBlankRegisterUserBody()) {
response.setStatusCode(StatusCode.REDIRECT);
response.addHeader(LOCATION, REGISTER_PAGE);
return;
}

Choose a reason for hiding this comment

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

실제 서비스를 생각한다면 이 경우에는 단순히 회원가입 페이지로 리다이렉트 되고 사용자는 리다이렉트 된 이유를 알지 못하고 계속 회원가입을 시도할 것 같아요.

사용자 편의성을 위해 예외 처리를 하고 클라이언트로 넘겨주는 건 어떻게 생각하나요??

Copy link
Author

@seokhwan-an seokhwan-an Sep 12, 2023

Choose a reason for hiding this comment

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

지금 당장 여기서 예외를 발생시키면 화면이 나타나지 않아 이 부분을 클라이언트가 알 수 있도록 잘못된 값을 입력했다는 것을 알 수 있게 bad request로 요청을 보내도록 수정했습니다. 즉, 공백을 넣어서 회원가입을 하면 "입력한 아이디, 비밀번호, 이메일에는 공백이 들어오면 안됩니다."의 문구가 나타나도록 수정했습니다!

Comment on lines 11 to 16
if (request.getHttpMethod() == HttpMethod.POST) {
doPost(request, response);
}
if (request.getHttpMethod() == HttpMethod.GET) {
doGet(request, response);
}

Choose a reason for hiding this comment

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

POST나 GET이 아닌 HttpMethod가 요청으로 들어오면 어떻게 될까요??

Copy link
Author

Choose a reason for hiding this comment

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

현재로서는 아무런 동작을 하지 않네요.. POST와 GET외에는 지원하지 메소드라는 예외처리를 진행하겠습니다.

Comment on lines +13 to +14
private static final Map<String, Controller> REQUEST_MAPPER = new HashMap<>();

Choose a reason for hiding this comment

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

Suggested change
private static final Map<String, Controller> REQUEST_MAPPER = new HashMap<>();
private static final Map<String, Controller> REQUEST_MAPPER = new HashMap<>();
private RequestMapping() {
}

인스턴스를 만들지 않는 유틸 클래스에는 private 기본 생성자를 추가해주세요..!

Utility classes, which are collections of static members, are not meant to be instantiated. Even abstract utility classes, which can be extended, should not have public constructors.

Java adds an implicit public constructor to every class which does not define at least one explicitly. Hence, at least one non-public constructor should be defined.

Copy link
Author

Choose a reason for hiding this comment

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

빼먹고 추가를 못했었네요 감사합니다!

Comment on lines 9 to 13
public class FileFinder {

private static final String FILE_PATH = "static/";
private static final String NOT_FOUND_PAGE = "404.html";

Choose a reason for hiding this comment

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

여기도 private 기본 생성자를 추가해주세요!

SonarCloud 참고

Copy link
Author

Choose a reason for hiding this comment

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

넵!!

Choose a reason for hiding this comment

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

쓰레드와 동시성 관련한 테스트는 저도 아직 제대로 감을 잡지 못해서 찾아보는 중입니다 😥
같이 고민해보아요..

Copy link
Author

Choose a reason for hiding this comment

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

저도 계속 찾아보았는데 방식이 떠오르지 않아서 이 부분 추가하지 못했습니다 ㅜㅜ

@sonarcloud
Copy link

sonarcloud bot commented Sep 13, 2023

Kudos, SonarCloud Quality Gate passed!    Quality Gate passed

Bug A 0 Bugs
Vulnerability A 0 Vulnerabilities
Security Hotspot A 0 Security Hotspots
Code Smell A 3 Code Smells

0.0% 0.0% Coverage
0.0% 0.0% Duplication

warning The version of Java (11.0.20.1) you have used to run this analysis is deprecated and we will stop accepting it soon. Please update to at least Java 17.
Read more here

@seokhwan-an
Copy link
Author

seokhwan-an commented Sep 13, 2023

망고 이번 리뷰받은 것 모두 반영했습니다. 추가적으로 가독성 향상을 위해 response 객체를 chainning 형식으로 heade와 body 등 값을 설정할 수 있게 수정했습니다. 또한 패키지 구조에 대해서 고민을 하고 controller(servlet)을 coyote에서 catalina 패키지로 이동했습니다!

Copy link

@Go-Jaecheol Go-Jaecheol left a comment

Choose a reason for hiding this comment

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

고생하셨어요 아코!!

피드백 반영 잘 해주셨네요 :) 톰캣 미션은 여기서 마무리할게요~~!!
질문에 대한 답변은 코멘트로 남겨두었습니다!

리뷰 주고받는 거 재밌었어요. 다음 MVC 미션도 화이팅 😎

@Go-Jaecheol Go-Jaecheol merged commit d14b143 into woowacourse:seokhwan-an Sep 14, 2023
2 checks passed
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