[영상후기] [10분 테코톡] 타칸의 Record

박철현·2024년 8월 15일
0

영상후기

목록 보기
151/160

movie

Record란 무엇일까?

불변 객체

  • Java로 프로젝트 진행 시 DB결과, 쿼리 결과, 서비스 정보와 같은 데이터를 단순히 담기 위한 객체를 생성하게 되는데 대부분 불변 객체를 사용
  • 불변 객체를 사용 함으로써 내부 필드값 불변 보장 -> 유지보수에서 많은 이점을 챙길 수 있음

Person 이라는 불변 객체를 만든다고 가정

  • name과 address라는 불변 객체를 담기 위함
  • 하지만 equals, hashCode, getter, toString 등 너무나 많은 메서드를 정의해줘야 한다는 단점
    • 소위 말하는 Bolierplate Code가 많다.
      • 최소한의 수정으로 여러 곳에서 자주 반복되는 코드
      • 생성자, equals 등 메서드
  • 만일 필드값이 추가된다면?
    • 기존에 정의된 Bolierplate 코드들이 모두 수정해야 하는 문제 필요
  • 단순히 name과 address의 속성만 담는 객체를 기대했는데, 너무 많은 메서드들이 생성되다 보니 의미가 퇴색될 수 있음
public class Person {
	private final String name;
    private final String address;
    
    public Person(String name, String address) {
    	this.name = name;
        this.address = address;
    }
    
    // equals, hashCode(), getter, toString

레코드의 등장

public record Person(String name, String address) {
}
  • 위 record와 이전 코드와 동일
    • 위처럼 정의해도 위 코드에 있던 Bolierplate 코드들이 자동으로 정의됨

어떻게 사용할까?

선언

public record Person(String name, String address) {
	// 내부 필드 선언 불가
    // 정적 필드 값은 가능
	private static final String value = "something";
}
  • 레코드는 선언과 동시에 내부에서 사용할 필드값들을 정의 해야함
    • 내부 필드 선언 시 에러 발생
    • static으로 된 정적 필드 추가 가능

호출

public record Person(String name, String address) {
}

Person person = new Person("타칸", "루터회관");

// 접근 : get이 붙지 않은 getter 호출
String name = person.name(); // 타칸
String address = person.address(); // 루터회관
  • 일반 객체처럼 사용
  • 필드 접근 시 get 이 붙지 않음

메서드 재정의

public record Person(String name, String address) {
	// Bolierplate 자동 생성하지만 재정의 하고자 하는 메서드는 재정의 해주면 됨
    @Override
    public String toString() {
    	return "닝겐입니다.";
    }
}
  • Bolierplate 자동 생성하지만 재정의 하고자 하는 메서드는 재정의 해주면 됨

생성자

일반 객체

public class Person {
	private final String name;
    private final String address;
    
    public Person(String name, String address) {
    	this.name = name;
        this.address = address;
    }

Record

public record Person(String name, String address) {

// 생성자에서 매개변수 부분 생략한 생성자
	public Person {
    // validate는 다른곳에서 정의한 메서드
    	validate(name, address);
    }
}
  • Record는 일반 객체와 다르게 Compact 생성자 기능 제공
    • 생성자에서 사용하는 파라미터와 레코드 필드 값이 서로 동일한 경우 생략할 수 있음
    • 초기화 로직은 마지막에 자동 호출(this.name = name)

왜 getXXX를 안쓸까??

  • 레코드는 일반 객체의 문제점을 해결하기 위해 등장한 것이 아니기 때문
    • 즉 레코드가 일반 객체의 컨벤션을 따를 필요는 없다고 볼 수 있음
    • 오라클 공식 문서 JEP 395
      • 레코드를 선언할 때 간결성을 제공하지만 보일러 플레이트와의 전쟁을 선언하는 것은 목표가 아니다.
      • 특히 자바빈 명명 규칙을 사용하는 일반 클래스의 문제를 해결하는 것은 목표가 아니다.

Lombok을 사용하면 안될까?

@Data
@AllArgsConstructor
public class Person {
	private final String name;
    private final String address;
}

public record Person(String name, String address) {
}
  • Lombok을 사용하면 보일러 플레이트 정리해주는 것과 유사한 기능
    • 가독성 측면 : 레코드가 좀 더 간결
    • 기능적 측면 : Data, 생성자, SLF4J와 같은 추가적 다양한 기능 제공
    • 의존성 측면
      • 롬복 : 외부 라이브러리기 때문에 별도 라이브러리 추가 필요, IDEA도 그에 맞는 플러그인 설치
      • Record : JDK16 이상 포함되어 별도 설치 없이 사용할 수 있음
  • 상황에 따라 사용
    • 간결하고 의존성 없는 프로젝트 -> 레코드가 더 나을듯
    • 기능과 유연성 -> 롬복이 더 나을듯

도메인 객체로 사용할 수 있을까?

  • 지양하는 것이 좋다
  • 오라클 공식 문서 JEP 395
    • 레코드는 불변 데이터를 전달하기 위한 캐리어다.
    • 단순한 값의 집합을 표현하는 객체 지향적인 구성을 고안한다.
    • 개발자가 확장 가능한 동작보다는 불변의 데이터 모델링에 집중할 수 있도록 도와준다.
  • 따라서 도메인 객체는 단순 데이터를 가지고 있는 것 뿐만 아닌 비즈니스 로직이 들어가기 때문에 단순히 데이터만 전달하기 위해 사용되는 레코드의 목적성에는 부합하지 않는다고 볼 수 있음
  • 도메인 객체 보다는 DTO에서 활용하는 것이 좋을 듯
profile
비슷한 어려움을 겪는 누군가에게 도움이 되길

0개의 댓글

관련 채용 정보