스프링과 자바를 사용하여 공부 중,

intellij에서 class가 아닌 record로 convet 할 수 있다는 추천을 보고 record에 대해 알아보고자하였다.
우선 record에 대해 알아보기 전에 불변객체에 대해 짚고 가야한다.
💡 Immutable Object(불변객체)객체지향 프로그래밍에서 불변 객체란, 생성 후 그 상태를 바꿀 수 없는 객체이다. 객체를 생성 후 값을 할당하면 내부 데이터를 변경할 수 없는 객체다.
대표적으로 wrapper class들 (String,Boolean,Integer 등)이 불변객체에 해당한다. 값을 수정하고 싶을 때는 값을 변경하는 것이 아니라 새로운 값의 객체를 new 로 생성해서 반환받는 것이다.
불변객체는 내부 필드값의 불변성을 보장함으로써 유지보수에 용이하다.
기존에 불변 데이터 객체를 생성하기 위해서는 아래의 여러 메서드들이 구현되어야했다.
- private final로 선언된 필드
- 각 필드에 대한 getter
- 전체 필드에 대한 생성자
- 모든 필드의 값이 일치하는지에 대한 정보를 반환하는 equals 메서드
- hashcode
- 디버깅을 위해 모든 필드의 이름과 값을 string으로 반환하는 toString 메서드
위의 모든 요소들을 boiler plate 코드가 방대해지는 것을 알 수 있다.
예시)
public class Person {
private final String name;
private final String address;
public Person(String name, String address) {
this.name = name;
this.address = address;
}
@Override
public int hashCode() {
return Objects.hash(name, address);
}
@Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
} else if (!(obj instanceof Person)) {
return false;
} else {
Person other = (Person) obj;
return Objects.equals(name, other.name)
&& Objects.equals(address, other.address);
}
}
@Override
public String toString() {
return "Person [name=" + name + ", address=" + address + "]";
}
// standard getters
}
이렇게 되면 필드가 추가될 때마다 생성자, toString() 외의 다른 보일러플레이트 코드를 모두 수정해야한다.
궁극적으로는 많은 코드가 추가됨으로써 데이터 값을 표현하는 클래스의 목적이 모호해지게된다.
우리가 알고 싶은 것은 Person의 각 필드의 값이기 때문이다.
Java16부터 Record를 활용하여 이를 해결할 수 있게됐다.
레코드는 불변 데이터를 전달하기 위한 캐리어다. 자바에서 Record를 사용하여 불변 객체를 쉽게 구현 가능하다.
위의 긴 보일러플레이트 코드를
public record Person(String name, String address) {}
이렇게 record 키워드를 사용하여 간단하게 나타낼 수 있다. equals(), hashCode(), toString() 메서드를 자동으로 생성해준다.
각 필드에 대한 접근 메서드(getter) 또한 자동으로 생성된다.
Person person = new Person("John Doe", "123 Main St");
String name = person.name(); // getter for name
String address = person.address(); // getter for address
person.getName()이 아니라 person.name()으로 접근한다는 점을 명심하자!
추가로, 부분 생성자나 자동으로 생성되는 메서드를 수정하여 커스텀 하고 싶다면 추가로 구현해주어야한다!
중요한 점은 Record는 클래스는 대체하기 위해 나온 것이 아니다. Record는 단순한 값의 집합을 표현하는 객체지향적인 구성을 가진다.
그럼 스프리에서 도메인에 Record를 사용할 수 있을까?
그렇지 않다. 비즈니스 로직을 처리하고 값이 수정될 수 있는 도메인에는 Record가 적합하지 않다.
대신 DTO에 record를 사용할 수 있다. DTO는 값을 전달하는 객체이다. 값이 수정되지 않고 전달만 되고, 받고 getter를 통해 필드의 값을 접근해야하는 목적에는 record가 부합하다고 할 수 있다.
요약하자면 확장 가능성과 유연성이 필요하다면 record는 적합하지 않고, 불변하는 데이터를 모델링하고 전달하는 목적에는 부합한다.
📎 참고 문서
https://www.baeldung.com/java-record-keyword
https://www.youtube.com/watch?v=MiHxFpTgAog