DTO는 Record를 사용해보자

DongGyun Cho·2023년 3월 26일

Java/Spring

목록 보기
3/3

일반적으로 DTO는 java class로 만들고

Getter, Setter, toString, equals, hashCode 등을 롬복 또는 일일이 입력해주면서 사용했다

거기다 DTO를 layer 마다 하나씩 만들어주거나

또는 복합적은 내용을 한번에 담은 DTO를 추가로 만들어 줄 때마다 계속 찍어내곤 한다.

물론 intellij에 plugin 중에 buddy라는 좋은 plugin이 있긴하지만 이제 유료(?)가 된것으로 알고있다

아무튼 Java 14에 새롭게 나온 record는 이런 DTO를 생성할 때 사용하면 굉장히 유용할 것 같이 보이는 신규 타입이다.

위에 말했던 기존 DTO를 만드는 방식으로 코드를 작성하면 아래와 같다.

public class Address {
    private String city;
    private String street;
    private String zipCode;

    public Address() {
    }
    
    public Address(String city, String street, String zipCode) {
        this.city = city;
        this.street = street;
        this.zipCode = zipCode;
    }

    public String getCity() {
        return city;
    }

    public String getStreet() {
        return street;
    }

    public String getZipCode() {
        return zipCode;
    }

    public void setCity(String city) {
        this.city = city;
    }

    public void setStreet(String street) {
        this.street = street;
    }

    public void setZipCode(String zipCode) {
        this.zipCode = zipCode;
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (!(o instanceof Address)) return false;
        Address address = (Address) o;
        return Objects.equals(city, address.city) &&
                Objects.equals(street, address.street) &&
                Objects.equals(zipCode, address.zipCode);
    }

    @Override
    public int hashCode() {
        return Objects.hash(city, street, zipCode);
    }
}

하지만 이런 똑같은 DTO를 record 타입으로 생성하게 된다면

public record Gundam(String name, String pilot, String series) {}

엄청 간략해 진다.

record 특징

  • record는 불변 객체로 abstract로 선언할 수 없으며 암시적으로 final로 선언됩니다. 한 번 값이 정해지면 setter를 통해 값을 변경할 수 없으며 상속을 할 수 없습니다.
  • record 내 각 필드(헤더에 나열한 컴포넌트)는 private final로 정의됩니다.
  • 다른 클래스를 상속 받을 수 없습니다만, 인터페이스로는 구현이 가능합니다. (extends : X, implements : O)
  • 레코드 내부에 멤버 변수(인스턴스 필드)를 선언할 수 없습니다. 그러나 static 변수는 생성이 가능합니다. 이는 헤더에서 정의한 멤버만을 record에서 관리하기 위함입니다.
  • 위의 4가지 주요 특징을 제외하고는 자바의 클래스 개발과 동일하게 사용할 수 있습니다.
    - new 키워드를 통해 객체화 가능
    - static 메소드, static 필드 선언 가능
    - 중첩 클래스 사용 가능 및 제너릭 타입으로 지정 가능

body의 재정의

record의 body 부분은 자동으로 생성된 메소드 혹은 새로운 메소드를 추가로 작성할 수 있습니다. 쉽게 생각해 클래스 내부에 작성한다고 보시면 됩니다.

public record Gundam(String name, String pilot, String series) {

    @Override
    public String toString() {
        return "Gundam{" +
                "override_name='" + name + '\'' +
                ", override_pilot='" + pilot + '\'' +
                ", override_series='" + series + '\'' +
                '}';
    }

	public boolean isFreedom() {
        return this.name.contains("freedom");
    }
}
profile
끈기를 가지고 해보자.

0개의 댓글