인프런 커뮤니티 질문&답변

이재영님의 프로필 이미지
이재영

작성한 질문수

스프링 핵심 원리 - 기본편

강의 자료

@qualifer 서비스단 구현시 질문이 있습니다.

작성

·

260

0


[질문 템플릿]
1. 강의 내용과 관련된 질문인가요? (예)
2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예)
3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예)

[질문 내용]
안녕하세요. 고급원리까지 다 듣고 토이프로젝트를 만들고 있는 1년차 개발자 입니다. 다름이 아니라,

서비스 단에서 @qualifer 를 활용하여 MemberService 인터페이스의 구현체인 SellerService , BuyerService 가 있습니다.

JPA 강의를 듣고 만들 던 도중에 Member Entity 를 추상화 클래스로 만들어서 조인방식으로 Seller , Buyer로 나누었고 outer join 으로 한번에 정보를 다 셀렉해오기 때문에 다운 캐스팅을 해서 Repository 에서 처리는 완만하게 추상화로 인한 문제는 해결이 됐습니다. 하지만..

서비스단 또한 겹치는 비니지스 로직이 많아서 인터페이스를 만들고 나누어서 구현체를 구현하고 컨트롤러에 @qualifer 를 활용해서 구현체 서비스를 각각 맵핑해주었는데, 이 때 인터페이스 MemberService 의 반환 값 제네릭에 대한 문제가 발생했습니다. 예를 들면,

Response<SellerListResponse> 와 Response<BuyerListResponse> 를 각각 사용해야하는데,

추상 클래스를 넣고 하자니 다운 캐스팅 시 번거로운 점이 너무 많습니다. 프로젝션스를 활용 하기 어렵게 느껴지고, MemberListResponse 의 값이 아닌 애들을 셋팅해야하는 작업등 많은 불편함이 있더라구요,

그래서 많이 고민해보고 구글링을 해보았는데, T 타입으로 선언을 해서 사용을 해서 사용하는 방법 뿐이 생각이 안납니다.

@qualifer를 활용할 때 반환타입에 대한 문제를 어떻게 해결하는지 궁금합니다.!!

답변 1

0

안녕하세요. qaz774433님, 공식 서포터즈 David입니다.

말씀하신 부분은 @Qualifier 를 사용할 때 나타나는 문제라기 보다 인터페이스와 구현체를 사용할 때 고민해야 하는 지점 같습니다.

말씀하신대로 seller와 buyer를 위해 구현체를 각각 만들어주고, 해당 구현체에서 SellerList, BuyerList를 각각 반환해주는 게 필요하다면 제네릭을 사용하셔서 처리하면 될 것 같습니다. 혹시 제네릭을 사용할 때 다른 고민이 있으신걸까요?

감사합니다.

 

안녕하세요 답변 감사합니다.

예를 들면 서비스 인터페이스에서 추상화 객체인 MemberListResponse 를 활용하게 되면, 

구현체에서 SellerListResponse 로 리턴하게 되어도 반환 값 오류가 난다는 점이 가장 컸습니다.

@GetMapping("/sale_member/list")
public Page<MemberListResponse> sellerList(@RequestBody SearchRequest searchRequest , Pageable pageable){
    return memberService.memberList(searchRequest , pageable);
}

위 처럼 작성하게 되면 return 에서 컴파일 에러가 나와서 고민했었어요 
T 타입으로 제네릭 선언을 하게 되면, 불분명함으로 인해 경고가 나와서 여러가지 찾아보다보니 런타임 에러를 유발할 수 있다고 해서요.
    첫번째.. 
    @GetMapping("/sale_member/list")
    public Page<? extends MemberListResponse> sellerList(@RequestBody SearchRequest searchRequest , Pageable pageable){
        return memberService.memberList(searchRequest , pageable);
    }

    2번째 방법 해쉬맵에 오브젝트넣어서 리턴..
    @GetMapping("/sale_member/list")
    public HashMap<Key, Object> sellerList(@RequestBody SearchRequest searchRequest , Pageable pageable){
        return memberService.memberList(searchRequest , pageable);
    }

이런 형식으로 두가지의 제한 하는 방법으로 반환을 진행해도 될까요? 

Service interface에서 제네릭에 무엇을 주는가가 궁금합니다!! 

응답하실 때 MemberListResponse 타입을 사용하시려는 이유가 있으실까요~?

응답할 때 MemberListResponse 대신 Seller~, Buyer~로 응답하셔도 무방해보여서요.

감사합니다..

응답자체는 그렇게 하고 있는데

제가 설명을 잘못하는 것같아서 사진으로..

인터페이스

image

이런형식으로 적게되면 Page에 Raw 경고가 나와서 타입에 따른 경고가 나와서..

sellerServiceImp 은

image

이렇고

image

바이어는 이렇기에.. 인터페이스 부분에서 제네릭을 설정할 때 어느 것이 좋은 방법인지 여쭤보고 싶습니다. 그래서 리턴 타입들을 저렇게 작성해보고 고민해본 것이에요!

image그래서 마지막은.. 이렇게 넣어두긴 했는데 어떤 방식이 옳은 것인지 잘모르겠습니다 ㅠ

회사에서는 주로 노드를 펑션형으로 작성하다보니 스프링 아키텍쳐부분이 많이 모자른 것같아요..

되물어서 죄송합니다 ㅠ

코드로 보여주셔서 감사합니다.

엄격하게 MemberListResponse의 서브클래스들로 제한하려면 지금 작성하신 것처럼 하셔도 괜찮을 것 같습니다.

친절한 답변 감사합니다!!

이재영님의 프로필 이미지
이재영

작성한 질문수

질문하기