1. 레코드(record)란?
- 자바 16부터 정식으로 도입
- 레코드는 데이터 중심의 클래스를 보다 간결하게 정의할 수 있도록 설계되었음
- 불변 객체를 쉽게 만들 수 있고, 자동으로 생성자, 접근자(getter), equals(), hashCode(), toString() 메서드를 제공함
- 레코드는 상속을 할 수 없고, 멤버 변수는 private final로 정의됨
롬복 + 애노테이션 조합도 좋다고 생각했는데, 이 보다 간결해질 수 있다니!! >.<
이번 개인 프로젝트를 진행할 때, DTO에 이 레코드를 적용하면 좋을 것 같다는 생각이 들었다.
2. DTO에 적용하기
우선, 레코드를 적용한 코드를 살펴보자!
MovieDefaultDto는 Movie 엔티티를 직접 노출*하는 대신에 DTO로 변환하여 사용하기 위해 만들어졌다.
* 엔티티를 직접 노출하는 것은 좋지 않다. 예를 들어 응답값으로 엔티티를 직접 외부에 노출한다고 가정해 보자! 기본적으로 엔티티의 모든 값이 노출되는데 이는 엔티티가 변경되면 API 스펙이 변한다는 의미와 같다. 또한, 실무에서는 같은 엔티티에 대해 용도에 따라 API가 다양하게 만들어지는데 한 엔티티에 각각의 API를 위한 모든 요구사항을 담기는 어렵다.
package com.happyprogfrog.movit.dto.movie;
import com.happyprogfrog.movit.model.Movie;
import java.time.LocalDateTime;
public record MovieDefaultDto(
Long movieId,
String title,
String director,
String summary,
String imageUrl,
LocalDateTime createdAt,
LocalDateTime updatedAt
) {}
만약, Movie 엔티티를 받아서 MovieDefaultDto 객체를 생성하고 싶다면 아래와 같이 코드를 추가하면 된다.
package com.happyprogfrog.movit.dto.movie;
import com.happyprogfrog.movit.model.Movie;
import java.time.LocalDateTime;
public record MovieDefaultDto(
Long movieId,
String title,
String director,
String summary,
String imageUrl,
LocalDateTime createdAt,
LocalDateTime updatedAt
) {
public MovieDefaultDto(Movie movie) {
this(
movie.getId(),
movie.getTitle(),
movie.getDirector(),
movie.getSummary(),
movie.getImageUrl(),
movie.getCreatedAt(),
movie.getUpdatedAt()
);
}
}
이렇게 하면,
- Movie 엔티티를 받아서 생성하는 생성자(public)
- 모든 멤버 변수를 인자로 하는 생성자(public, 자동 생성)
총 2개의 생성자를 사용할 수 있다.
추가로, 디컴파일된 코드를 확인하면 특이한 점이 하나 있다는 것을 알 수 있다.
바로 getXxx()와 같이 getter를 구현한 것이 아니라, 멤버 변수의 이름으로 메서드를 만들었다는 점이다!
그래서 다음과 같이 defaultDto.movieId()처럼 사용할 수 있다.
3. 기타
내가 사용하면서 느꼈던 장점들을, 역시나 다른 분도 느끼고 있었음ㅋㅋㅋ
잘 정리해주신 분이 있어서 스크랩~~
배운 걸 적용해 보는 일은 너무 재밌다.
달려봅시다!!🏃🏃♀️🏃🏃♀️🏃🏃♀️
반응형