우아한 테크코스 2주 차 프리코스 미션을 하면서 JDK17의 특징을 살릴 수 있는 레코드 (record)에 대해 접해볼 수 있었습니다.
사용하면서 느낀 점은, 기존에 작성했던 DTO를 쉽게 대체할 수 있겠다는 생각이었습니다.
(DTO가 무엇인지를 보시려면 이 글을 참고해주세요!)
기존의 DTO
먼저, 기존에 사용했던 DTO 코드의 예시를 보겠습니다.
public class CarResponse {
private final String name;
private final int position;
private CarResponse(final String name, final int position) {
this.name = name;
this.position = position;
}
public static CarResponse of(final String name, final int position) {
return new CarResponse(name, position);
}
public String getName() {
return name;
}
public int getPosition() {
return position;
}
}
- final 필드를 정의합니다.
- 생성자를 정의합니다.
- (커스텀이지만) 정적 팩토리 메서드를 정의합니다.
- 각 필드에 대한 getter 메서드가 있습니다.
레코드 도입 후
public record CarResponse(String name, int position) {
public static CarResponse of(final String name, final int position) {
return new CarResponse(name, position);
}
}
// 필드 사용 예시
// DTO: carResponse.getName()
// 레코드: carResponse.name()
- 필드 정의를 클래스 이름 옆에 선언합니다.
- 커스텀한 정적 팩터리 메서드 이외의 모든 코드가 필요 없어집니다.
이렇듯 DTO를 정의하는 데 있어 레코드는 매우 편리합니다. 어떤 장단점들이 있는지, 특징은 무엇인지 알아봅시다!
레코드의 장점 & 특징
1. 코드 작성량 축소
가장 와닿는 점입니다. 기존에 DTO를 정의하기 위해 작성해야 했던 코드 작성량이 획기적으로 줄어들었음을 볼 수 있습니다.
2. 목적을 명확히 전달함
기존 DTO 코드는 일반적인 클래스 파일을 작성한 뒤, final 속성을 붙이고 setter를 사용하지 않는 등의 작업을 해야만 이것이 불변 객체를 의미하며 DTO의 목적 (데이터 전달)을 수행한다고 알려줄 수 있었지만, 레코드는 기본적으로 불변임을 보장하기 때문에 이러한 작업을 하지 않아도 불변 객체임을 나타낼 수 있으며 그렇기에 데이터 전달에도 활용될 수 있음을 보장합니다.
3. getter, toString, hashCode, equals 지원
기본적인 getter, toString, hashCode, equals 메서드가 내장되어 있습니다. 물론 toString, hashCode, equals를 재정의할 수 있긴 합니다.
4. 인터페이스 구현 지원
일반적인 클래스처럼 특정 인터페이스의 구현체가 될 수 있습니다.
5. 콤팩트 생성자 (compact constructor) 지원
생성 시 특정 조건을 걸게 할 수도 있습니다.
public record HelloWorld(String message) {
public HelloWorld {
java.util.Objects.requireNonNull(message); // message에 null이 들어갈 시 NPE가 발생합니다.
}
}
이 외에도 중첩 레코드 클래스를 만들어두거나 (암묵적으로 static입니다.), 제네릭 레코드를 만들어둘 수도 있습니다.
레코드의 단점 & 제약사항
1. 인스턴스 필드 생성 불가
레코드에서는 인스턴스 필드 생성이 불가능합니다. 필드를 생성하려면 정적 필드만 가능합니다.
2. 생성자 접근자 변경 불가능
기본 생성자를 아예 사용하지 않고 정적 팩토리만으로 DTO를 만들어왔었는데, 이 점이 살짝 아쉽습니다.
3. 상속 불가능
다른 객체로부터 상속받는 것은 불가능합니다.
사용 후기
매우 획기적으로 보일러 플레이트 코드들을 없애주고, 불변을 보장해서 유용하게 쓰고 있습니다.
비단 DTO 뿐 아니라, 불변성을 보장한다는 점에서 VO (Value Object)로도 활용될 수 있을 것 같다는 생각이 듭니다.
만약 위의 단점, 제약사항이 있어도 괜찮으면서 & JDK16 이상의 자바로 실행한다면 레코드를 사용하는 것도 괜찮을 것 같다고 느꼈습니다 😃
틀린 점이 있다면 바로 수정하도록 하겠습니다!
참고 문서
'☕️ Java' 카테고리의 다른 글
"원시값 포장"에 대해 알아보자 (0) | 2023.11.01 |
---|