해결된 질문
작성
·
568
·
수정됨
1
public static MockHttpServletRequestBuilder get(String urlTemplate, Object... urlVariables) {
return MockMvcRequestBuilders.get(urlTemplate, urlVariables)
.requestAttr(RestDocumentationGenerator.ATTRIBUTE_NAME_URL_TEMPLATE, urlTemplate);
}
위의 코드는 RestDocumentationRequestBuilders의 get()입니다.
Spring REST Docs2 - 요청, 응답필드의 9:27에서 하신 말씀 듣고 상속 관계이지 않을까하는 생각이 들었고 궁금해서 들어가보니 상속이 아닌
RestDocumentationRequestBuilders의 get()에서 내부적으로 MockMvcRequestBuilders의 get()를 호출해주더라구요.
MockMvcRequestBuilders가 추상클래스지만 get()이 static으로 선언되어 있어 상속을 해도 오버라이드를 할 수 없기에 저런 식으로 만들었지 않았을까?
라고 추측을 해봤습니다.
그러면서 추가적으로 위의 클래스들이 추상클래스로 만들어져 있고 메소드가 전부 static으로 선언되어 있는 것에 대해 이유가 궁금했습니다.
추상클래스는 추상 메소드를 선언하고 상속을 하면서 오버라이드를 통한 다형성을 위해 사용한다고 알고 있었는데 여기서는 다른 목적과 방식으로 사용하고 있는 것처럼 보였기 때문입니다.
그래서 검색을 해봤지만 키워드를 잘못 선택했는지
명확하게 답을 찾지는 못했고, 추상 클래스와
스태틱 메소드에 대해 각각 찾아보면서
"객체 생성 제한과 메모리 이득 때문인가?"
라는 생각이 들더라구요.
하지만 추상클래스도 익명객체를 사용하면 객체 생성이 가능해지는 걸로 아는데 그래서인지RestDocumentationRequestBuilders는 생성자도 private으로 선언해 익명 객체로도 생성이 안되게 막아 놨지만 MockMvcRequestBuilders같은 경우는 생성자를 따로 막아 놓지 않아서 익명 객체로 생성이 가능하더라구요. 이렇게 차이를 두는 이유는 뭔가요??
그리고 위의 클래스들처럼 선언한 이유도 궁금합니다.
답변 1
1
안녕하세요, 인프런 AI 인턴이에요.
RestDocumentationRequestBuilders의 get() 메서드에서 MockMvcRequestBuilders의 get() 메서드를 호출하는 것은 상속 관계가 아닌, 단순한 메서드 호출입니다. RestDocumentationRequestBuilders는 MockMvcRequestBuilders를 사용하는 편의 메서드를 제공하기 위해 만들어진 클래스인데요. 상속이 아닌 이유는 MockMvcRequestBuilders가 추상 클래스이면서 get() 메서드가 static으로 선언되어 있기 때문에 상속을 받아서 오버라이드 할 수 없기 때문입니다.
추상 클래스는 추상 메서드를 선언하고 상속을 통해 다형성을 위해 사용하는 경우가 많지만, 이 경우에는 다른 목적과 방식으로 사용하고 있기 때문에 헷갈릴 수 있습니다. RestDocumentationRequestBuilders는 RestDocumentation에 필요한 편의 기능을 제공하기 위해, MockMvcRequestBuilders와 같은 메서드를 사용하고 있습니다. 이를 통해 사용자가 RestDocumentation을 더 쉽게 활용할 수 있도록 도와줍니다.
추상 클래스는 상속을 통해 다형성을 구현할 수도 있지만, 다양한 목적으로 활용될 수도 있습니다. 메서드가 static으로 선언되어 있는 이유는 특정한 인스턴스에 의존하지 않고도 사용할 수 있기 때문입니다. static 메서드는 클래스 레벨에서 바로 호출이 가능하므로, 인스턴스 생성 없이도 사용할 수 있습니다.
추가적인 검색을 하려는데 어떤 키워드를 사용하셨는지 알려주시면 더 도움을 드릴 수 있을 것 같아요.
난해한 질문이었을텐데 친절한 답변 감사합니다ㅜㅜ
처음에는 저 둘 클래스에 메서드 시그니처가 같은 부분이 많아서
상위에 추상클래스나 인터페이스를 따로 만들고 구현하는게 더 좋지 않나? 라는 생각과
어짜피 상속 상관없이 메서드를 static으로만 정의할거면 왜 추상클래스로 했지? 라는 생각만
들고 무슨 이유인지 잘 모르겠더라구요.
질문 올려놓고 좀 더 찾아보니 이런 유형을 유틸리티 클래스라고 하는 것 같더라구요.
유틸리티 클래스라는 키워드로 더 찾아보니 제가 궁금했던 답을 찾을 수 있었습니다.
그리고 이펙티브 자바에서도 나오는 내용이었네요... 어서 빨리 읽어봐야겠어요
호돌맨님이 만약 이거 찾아보라고 안 던져 주셨으면 모르고 지나갈 뻔했습니다 ㅜㅜ
감사합니다..
혹시나 궁금하신 분들은 밑에 링크나 이펙티브 자바를 보시면 될거 같습니다.
추상클래스로 선언된 유틸 클래스 : https://mangkyu.tistory.com/238
유틸 클래스 생성자 private : https://log-laboratory.tistory.com/220
유틸 클래스 vs Bean : https://hyeonic.github.io/study/agora/2022-06-16.html#%E1%84%8B%E1%85%A1%E1%84%80%E1%85%A9%E1%84%85%E1%85%A1