-
Notifications
You must be signed in to change notification settings - Fork 3
Dto VS Record
Lee kangmin edited this page Sep 17, 2024
·
2 revisions
- record 타입은 Java 16에서 도입된 데이터 구조로, 필드 선언과 함께 간단하게 자동으로 getter, toString, equals, hashCode, constructor 등을 생성해주는 역할을 합니다. 기본적으로 record의 body는 비어있을 수 있지만, 필요한 경우 다음과 같은 내용을 포함할 수 있습니다.
-
추가적인 메서드
- record는 필요한 경우 메서드를 추가할 수 있습니다. 일반적인 클래스처럼 비즈니스 로직이나 데이터를 가공하는 메서드를 포함할 수 있습니다. -
-
정적 메서드(static method)
- 클래스처럼 정적 메서드를 정의할 수 있습니다.
-
정적 필드(static field)
- 정적 필드도 포함 가능합니다.
-
인스턴스 초기화 블록(instance initializer block)
- 객체가 생성될 때 실행되는 초기화 블록을 정의할 수 있습니다.
-
커스텀 생성자
- record는 기본 생성자를 자동으로 생성하지만, 필요한 경우 생성자를 커스터마이징할 수 있습니다. 예를 들어, 필드에 대한 추가적인 유효성 검사를 포함하는 생성자를 만들 수 있습니다.
-
추가 인터페이스 구현
- record는 다른 인터페이스를 구현할 수 있습니다.
public record LeagueCreateRequest(
String name,
String description,
String tierLimit,
String status,
String matchType,
LocalDateTime leagueAt,
LocalDateTime closedAt,
Long playerCount,
LocalDateTime createdAt,
LocalDateTime modifiedAt
) {
// 커스텀 생성자 (유효성 검사)
public LeagueCreateRequest {
if (playerCount < 0) {
throw new IllegalArgumentException("Player count cannot be negative.");
}
}
// 정적 메서드
public static LeagueEntity createRequestToEntity(LeagueCreateRequest request) {
return new LeagueEntity(
request.name(),
request.description(),
request.leagueAt(),
request.tierLimit(),
request.closedAt(),
request.status(),
request.playerCount(),
request.matchType(),
request.createdAt(),
request.modifiedAt()
);
}
}
dto는 아래와 같이 어노테이션을 많이 붙인다.
@Builder
@Getter
@AllArgsConstructor
@RequiredArgsConstructor
@JsonNaming(PropertyNamingStrategies.SnakeCaseStrategy.class)
@ToString
public class LeagueCreateRequest {
@Schema(description = "경기 이름", example = "배드민턴 경기")
private String name;
// .. 이하 내용 생략
}
반면 record는 Getter Builder 등 기본적으로 적용하는 기능이 많아 생략이 가능하다.
@JsonNaming(PropertyNamingStrategies.SnakeCaseStrategy.class)
public record LeagueCreateRequest(
@Schema(description = "경기 이름", example = "배드민턴 경기")
String name,
Dto 객체를 불변성으로 만들기 위해서는 setter를 사용하지 않는 방법이 있지만 메서드를 통해서 변경이 가능하다. 만약 객체의 불변성을 보장하고 객체의 값이 변하지 않는 것이 더 나은 선택이라면 Record 타입의 객체도 좋은 것 같다.
public record Person(String name, int age) {
// 생성자에서 유효성 검사 가능
public Person {
if (age < 0) {
throw new IllegalArgumentException("Age cannot be negative.");
}
}
}
//객체의 불변성 보장
public class Main {
public static void main(String[] args) {
Person person = new Person("Alice", 30);
// 값 읽기
System.out.println(person.name()); // 출력: Alice
System.out.println(person.age()); // 출력: 30
// person의 필드를 수정하려고 하면 오류 발생 (불변성 보장)
// person.name = "Bob"; // 컴파일 오류
// 새로운 객체를 생성해서 수정된 값을 할당해야 함
Person updatedPerson = new Person("Bob", 35);
System.out.println(updatedPerson.name()); // 출력: Bob
System.out.println(updatedPerson.age()); // 출력: 35
}
}
아직 까지는 Dto의 객체의 값을 변경시키거나 값을 재할당하는 일은 없다. 객체의 불변성을 보장하면서 정적팩토리 메서드를 사용해야 한다면 Record 타입을 고려해보는 것이 어떨까?