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단계] 리오(오영택) 미션 제출합니다. #496

Merged
merged 25 commits into from
Sep 14, 2023

Conversation

Jaeyoung22
Copy link

@Jaeyoung22 Jaeyoung22 commented Sep 11, 2023

안녕하세요 로이스!

시간이 없어서 테스트를 다 못 짰네요ㅠㅠ

우선 프로덕션 코드 쪽만 리뷰해주실 수 있으실까요?
급하게 PR 날리느라 코드 설명도 첨부못해서 죄송합니다ㅠㅠㅠㅠ
common 패키지 내부에 인터페이스들로 추상화를 해서 의존성을 분리하려고 해봤어요

리뷰 잘 부탁드립니다 감사합니다요

Copy link
Member

@TaeyeonRoyce TaeyeonRoyce left a comment

Choose a reason for hiding this comment

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

리오! 코드 잘 봤습니다!👍👍👍
패키지 뿐만 아니라 전체적인 계층과 구조에 대해 깊은 고민이 담긴 코드라 인상 깊었습니다.
구성 속에서도 디테일이 많아 좋았습니다.
mocking을 통해 타겟 메서드에 집중하여 테스트를 정말 잘 구성하신 것도 인상 깊네요.

구조 관련하여 리오의 의도와 생각이 궁금하여 남긴 코멘트들을 몇가지 남겼는데요.
답장 남겨주시면 감사하겠습니다!
고생하셨어요!


@Configuration
public class CacheWebConfig implements WebMvcConfigurer {

@Override
public void addInterceptors(final InterceptorRegistry registry) {
WebContentInterceptor webContentInterceptor = new WebContentInterceptor();
Copy link
Member

Choose a reason for hiding this comment

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

WebContentInterceptor는 어떤 역할을 하나요?

Copy link
Author

Choose a reason for hiding this comment

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

학습테스트에서 캐시를 설정해주는 역할입니다!

@@ -0,0 +1,9 @@
package common;
Copy link
Member

Choose a reason for hiding this comment

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

Constants의 값들 모두 apache package 에서만 사용되는데 apache 내부가 아닌 동일 계층으로 두신 이유가 있을까요?

Copy link
Author

Choose a reason for hiding this comment

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

jwp 패키지에서도 사용될 것 같아서 넣어놨는데 안 쓰이게 됐군요..! 변경하겠습니다! 감사합니다~!

public static final String SPACE = " ";
public static final String CRLF = "\r\n";

private Constants() {}
Copy link
Member

Choose a reason for hiding this comment

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

static 클래스에 인스턴스화 방지👍

Enum을 사용하면 추후 reflection을 통한 생성 대해서도 방지 할 수 있습니다!


protected void doPost(Request request, Response response) { /* NOOP */ }

protected void doPut(Request request, Response response) { /* NOOP */ }
Copy link
Member

Choose a reason for hiding this comment

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

해당 메스드는 구현하지 않은 핸들러에게 이 메서드의 요청이 오면 어떻게 되나요?
ex)
DELETE /login HTTP/1.1

Copy link
Author

Choose a reason for hiding this comment

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

지금은 abstractController의 메서드가 호출되어 아무일도 일어나지 않는군요..! 해당 예외도 처리하도록 하겠습니다!

}

@Override
public String toString() {
Copy link
Member

Choose a reason for hiding this comment

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

전반적으로 출력과 관련한 로직을 toString()을 Override하셨는데요.
java doc도 그렇고 effective java에서도 toString()의 재정의를 권장하고 있습니다.

toString()은 디버깅의 목적 등으로 해당 객체에 대한 정보를 사람이 읽기 쉬운 간결하지만 유익한 표현을 반환하도록 사용된다고 이해했습니다.

전반적으로 toString()이 단순 객체의 정보 전달이 아닌 출력(뷰) 형식에 의존적인 로직이 포함되어 있는 것 같아서요. (관례적으로 쓰는 getXxx(), setXxx() 네이밍의 객체를 보면 기대하는 로직이 있지 않으신가요?!)

저는 toString()메서드를 보았을 때, 뷰 로직이 담겨있을 거라곤 기대하지 않았었습니다!
먼저, 다른 메서드이름을 사용해보는건 어떨까요?
출력에 관련한 로직의 분리가 필요한지는 좀 더 고민해보고 결정해보죠!

Copy link
Author

Choose a reason for hiding this comment

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

확실히 toString 보다는 다른 메서드 명을 사용하는 것이 나을 것 같네요!


private void serviceIfHasStaticResourcePath(HttpRequest httpRequest, HttpResponse httpResponse) {
if (httpRequest.hasStaticResourcePath() || httpResponse.hasStaticResourcePath()) {
controllerManager = new StaticControllerManager();
Copy link
Member

Choose a reason for hiding this comment

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

여러 쓰레드를 통해 process가 수행 될 때 마다 new StaticControllerManager()가 실행 되는데, 이 부분도 개선 하면 좋겠습니다!
StaticControllerManager의 인스턴스 변수가 없으니 싱글톤으로 제공해도 괜찮아 보여요

Copy link
Author

Choose a reason for hiding this comment

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

저도 이 부분을 참 많이 고민했었는데요,
sonar lint에서 자꾸 냄새난다고 하는 게 짜증나기도 하고 그래서 일단 매번 생성하도록 했습니다.
싱글턴으로 다시 바꿔볼게요! (5번째 바꾸는...)

this.httpRequestBody = httpRequestBody;
}

public HttpMethod getHttpMethod() {
Copy link
Member

Choose a reason for hiding this comment

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

Override 붙혀주세요!


void validateLength(long length) {
if (length != body.getBytes().length) {
throw new IllegalArgumentException("Response Body의 길이가 유효하지 않습니다.");
Copy link
Member

Choose a reason for hiding this comment

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

발생할 수 있는 상황에 대해 꼼꼼하게 처리하셨군요!👍👍

public static final String LOCATION = "Location";
public static final String RESOURCE_PATH = "Resource-Path";

private final Map<String, List<String>> headers;
Copy link
Member

Choose a reason for hiding this comment

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

value를 List 관리한 이유가 있나요?
단순 String으로 사용해도 문제가 없어보입니다!

Copy link
Author

Choose a reason for hiding this comment

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

같은 필드에 대해서 여러 밸류가 존재할 수 있습니다!
예를 들어 쿠키 같은 경우도 여러 개를 실어줄 수 있겠죠..?! ^^

HTTP/1.1 200 OK
Content-Type: text/html
Set-Cookie: cookie1=value1; Expires=Wed, 21 Oct 2023 07:28:00 GMT
Set-Cookie: cookie2=value2; Path=/; Secure
Set-Cookie: cookie3=value3; HttpOnly

Copy link
Member

Choose a reason for hiding this comment

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

엇 그렇네요!
리오 말씀대로 구현하는게 범용적이고 좋네요!! 감사합니다👍

@Test
void POST요청시_이미_가입된_회원이면_예외를_반환한다() {
// given
InMemoryUserRepository.save(new User("로이스", "잘생김", "내마음속"));
Copy link
Member

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 14, 2023

SonarCloud Quality Gate failed.    Quality Gate failed

Bug A 0 Bugs
Vulnerability B 1 Vulnerability
Security Hotspot A 0 Security Hotspots
Code Smell A 2 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

idea Catch issues before they fail your Quality Gate with our IDE extension sonarlint SonarLint

Copy link
Member

@TaeyeonRoyce TaeyeonRoyce left a comment

Choose a reason for hiding this comment

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

리오, 미션동안 고생 많으셨습니다!
질문에 답변도 다 남겨주셔서 리오의 의도와 코드를 이해하는데 도움이 많이 되었습니다.
새로운 개념에 대한 깊은 학습을 하셨다는 인상을 받았고, 이를 토대로 여러 부분들을 고려하면서 꼼꼼하게 작성 된 코드가 인상 깊었습니다! 고생하셨어요~!

다음 미션도 화이팅입니다~!👍

@TaeyeonRoyce TaeyeonRoyce merged commit 490ed84 into woowacourse:jaeyoung22 Sep 14, 2023
1 of 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