Inflearn brand logo image

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

yg04076님의 프로필 이미지
yg04076

작성한 질문수

Readable Code: 읽기 좋은 코드를 작성하는 사고법

DTO 생성과 관련해서 궁금한 게 있습니다!

작성

·

130

·

수정됨

0

  • 학습 관련 질문을 남겨주세요. 어떤 부분이 고민인지, 무엇이 문제인지 상세히 작성하면 더 좋아요!

  • 먼저 유사한 질문이 있었는지 검색해 보세요.

  • 서로 예의를 지키며 존중하는 문화를 만들어가요.

     

@Transactional
    public ShelterResponse.FindShelterListDTO findActiveShelterList() {
        List<Shelter> shelters = shelterRepository.findAllWithAnimalAndLatitude();

        List<ShelterResponse.ShelterDTO> shelterDTOS = shelters.stream()
                .map(shelter -> new ShelterResponse.ShelterDTO(
                        shelter.getId(),
                        shelter.getName(),
                        shelter.getLatitude(),
                        shelter.getLongitude(),
                        shelter.getCareAddr(),
                        shelter.getCareTel()))
                .collect(Collectors.toList());

        return new ShelterResponse.FindShelterListDTO(shelterDTOS);
    }

    @Transactional(readOnly = true)
    public ShelterResponse.FindShelterInfoByIdDTO findShelterInfoById(Long shelterId) {
        Shelter shelter = shelterRepository.findById(shelterId).orElseThrow(
                () -> new CustomException(ExceptionCode.SHELTER_NOT_FOUND)
        );

        return new ShelterResponse.FindShelterInfoByIdDTO(
                shelter.getId(),
                shelter.getName(),
                shelter.getLatitude(),
                shelter.getLongitude(),
                shelter.getCareAddr(),
                shelter.getCareTel(),
                shelter.getAnimalCnt()
        );
    }

 

위 코드는 유기 동물 보호소 서비스에서 보호소 목록을 가져오고, 보호소의 상세 정보를 가져오는 코드입니다.

서비스 레이어에서 컨트룰러 레이어로 응답을 내보낼 때 DTO로 변환해서 보내는데, 데이터양이 많은 엔티티의 경우 위 코드처럼 DTO 빌드 코드가 길어지더라구요..

 

그래서, 정보량이 많은 엔티티에 관한 데이터를 DTO로 리턴할 때는 아래와 같이 서비스 레이어에 private 메서드로 추출해서 사용합니다.

private ShelterResponse.AnimalDTO createAnimalDTO(Animal animal, List<Long> userLikedAnimalIds) {
        return new ShelterResponse.AnimalDTO(
                animal.getId(),
                animal.getName(),
                animal.getAge(),
                animal.getGender(),
                animal.getSpecialMark(),
                animal.getKind(),
                animal.getWeight(),
                animal.getNeuter(),
                animal.getProcessState(),
                animal.getRegion(),
                animal.getInquiryNum(),
                getCachedLikeNum(animal.getId()),
                userLikedAnimalIds.contains(animal.getId()),
                animal.getProfileURL());
    }

 

여기서 고민이 시작 됐는데, 응답으로 보낼 DTO를 빌드하는 로직을 서비스 레이어에 private 메서드로 추출하는 게 서비스 레이어의 역할 상 괜찮을지 의문이 들더라구요.

현업에서는 정보량이 많은 DTO 코드를 빌드하는 부분을 메서드로 따로 추출하는지, 추출한다면 어떻게 처리하는지 궁금합니다!

이거를 메서드로 추출하지 않을까도 생각해봤는데, 그러면 메서드의 코드 길이가 너무 길어져서 가독성을 해치는 느낌도 있더라구요.. 또 DTO만 처리하는 클래스를 만들어볼까도 생각했는데 이게 맞나 싶기도 하구요

 

 

답변 2

1

박우빈님의 프로필 이미지
박우빈
지식공유자

안녕하세요, yg04076 님!

DTO 내부에 변환 로직을 두면 서비스는 깔끔해지지 않을까요?
AnimalDTO.of(animal, ...) 과 같이 각 DTO에 정적 팩토리 메서드를 만들고, 필요한 정보를 파라미터로 받아 내부에서 변환하도록 하면 될 것 같아요.

감사합니다. 🙂

0

안녕하세요, 인프런 AI 인턴입니다. yg04076님께서 질문해 주신 내용은 DTO(Data Transfer Object) 생성 및 관리에 관한 사항으로 보입니다. 현실적인 개발 상황에서는 종종 데이터의 복잡성과 양이 커지면서 DTO 생성 코드가 복잡해질 수 있습니다. 이런 경우 다음과 같이 다양한 접근 방식을 고려해볼 수 있습니다.

  1. Private 메서드로 추출: 현재와 같은 방식으로, 서비스 레이어 내에서 private 메서드로 DTO를 생성하는 코드를 분리할 수 있습니다. 이를 통해 코드의 중복성을 줄이고 가독성을 높일 수는 있지만, 서비스 레이어의 책임이 과중되지 않도록 주의해야 합니다.

  2. DTO 전용 변환 유틸리티 클래스 생성: DTO를 변환하는 로직을 별도의 유틸리티 클래스나 변환기 클래스로 분리하여 사용할 수도 있습니다. 이 방법은 서비스 레이어를 깔끔하게 유지하면서 변환 로직을 재사용할 수 있도록 합니다. 예를 들어 ShelterDTOConverter 같은 클래스를 만들고, 여기서 변환 로직을 책임지게 할 수 있습니다.

  3. 모델 매퍼 활용: ModelMapper와 같은 라이브러리를 활용하는 것도 좋은 방법입니다. 이는 객체 간의 변환을 자동화하여 수작업 코드를 줄이고 매핑을 보다 선언적으로 처리할 수 있도록 도와줍니다.

  4. Builder 패턴 사용: 데이터가 많고 생성이 복잡한 경우 빌더 패턴을 활용하여 DTO 생성 과정을 직관적으로 만들 수 있습니다. 이렇게 하면 코드의 가독성을 높일 수 있습니다.

관련된 보다 자세한 논의와 유사한 사례를 controller, service용 dto를 분리시키는 것에 대한 질문에서 찾아 참고하실 수 있습니다.

이와 같은 다양한 방법을 검토하시면서 프로젝트의 성격과 팀의 컨벤션에 맞추어 적합한 방법을 선택하시면 좋겠습니다.

저는 질문자님의 이해를 돕고자 지식공유자님의 기존 답변을 참고하여 유사한 답변 링크를 추천해드리고 있습니다. 현재 베타 기능으로 답변이 만족스럽지 않을 수 있는 점 양해 부탁드립니다. 🙏 추가적으로 궁금한 점이 있으시면, 이어서 질문해 주세요. 곧 지식공유자께서 답변해 주실 것입니다.

yg04076님의 프로필 이미지
yg04076

작성한 질문수

질문하기