Record는 Java 16에서 정식 도입된 특별한 유형의 클래스로, 불변성(Immutable)을 기본으로 합니다. 필드가 final
로 선언되어 객체 생성 이후 변경이 불가능하며, 생성자, getter
, equals()
, hashCode()
, toString()
메서드를 자동으로 생성하여 불필요한 코드를 줄일 수 있습니다.
이러한 특성 덕분에 멀티스레드 환경에서도 안전하게 데이터를 전달할 수 있어 DTO로 사용하기 적합합니다.
1. 기존 클래스 기반 DTO
public class MemberDto {
private final String name;
private final String email;
private final int age;
public MemberDto(String name, String email, int age) {
this.name = name;
this.email = email;
this.age = age;
}
public String getName() {
return name;
}
public String getEmail() {
return email;
}
public int getAge() {
return age;
}
}
2. Record 기반 DTO
public record MemberDto(String name, String email, int age) {}
Record의 장점:
- 생성자,
getter
,hashCode()
,equals()
,toString()
메서드 자동 생성- 코드 간결화로 유지보수 용이
- 불변성 보장
모든 Record 객체가 DTO인 것은 아닙니다. Record는 데이터를 캡슐화하기 위한 도구로, DTO 외에도 값 객체(Value Object, VO) 등 다양한 용도로 사용될 수 있습니다.
DTO(Data Transfer Object):
데이터 계층 간 전송을 목적으로 설계된 객체로, 비즈니스 로직이 없는 단순한 데이터 구조입니다.
VO(Value Object):
도메인 모델 내에서 특정 값을 표현하는 객체로, 값 기반의 동등성을 가지며 비즈니스 로직을 포함할 수 있습니다.
public record Coordinates(double x, double y) {}
결론:
Record는 DTO와 VO 모두에 적합하지만, 사용 목적에 따라 설계와 구현 방법이 달라집니다.
특징 | Record | VO (Value Object) |
---|---|---|
불변성 | 불변 필드를 기본으로 제공 | 불변 필드를 요구, 동등성 보장 |
주요 목적 | 데이터 전달 (DTO 역할) | 도메인 모델의 특정 값 표현 |
비즈니스 로직 | 포함하지 않음 | 포함 가능 |
동등성 | 필드 값 기반으로 동등성 판단 | 동일 |
클래스 상속 불가:
Record는 extends
를 지원하지 않으므로 상속 구조를 활용한 설계가 어렵습니다.
확장성 제한:
모든 필드가 final
로 선언되어 객체 상태 변경이 불가능하며, 추가적인 상태 변경 로직을 포함하기 어렵습니다.
비즈니스 로직 부적합:
Record는 데이터를 표현하기 위해 설계되었으며, 비즈니스 로직을 담기에 적합하지 않습니다.
버전 호환성:
Java 16 이상에서만 지원되므로, 이전 버전(Java 14 이하)에서는 사용할 수 없습니다.
Record는 간결한 코드 작성과 불변성을 보장하여 DTO 설계에 매우 유용합니다. 다만, VO로도 활용될 수 있지만, 도메인 로직과의 결합이 필요한 경우 VO 고유의 설계가 더 적합할 수 있습니다. Record를 선택할 때는 프로젝트의 설계 요구 사항과 사용 목적을 고려해야 합니다.