Java-Chip4 / StudyingRecord

강의 내용 정리📝
6 stars 2 forks source link

@Data 사용을 지양해야 되는 이유는 뭘까? #55

Open nmsgust opened 2 years ago

nmsgust commented 2 years ago

스프링 MVC 1편 - 상품도메인개발 에서 @Data는 예측할 수 없게 동작할 수 있기 때문에 사용을 지양하고 필요한 것만 분리해서 사용하라고 하셨다. 이때 @Data의 사용을 지양 해야 되는 이유는 무엇일까?

@Data는 Lombok 라이브러리에 있는 어노테이션으로 총 5가지의 어노테이션 설정을 포함하고 있다.

Lombok

기본적으로 웹 애플리케이션에서 사용하는 VO 객체는 DB 테이블의 column 과 같은 이름의 private 변수를 가지고, getter setter 메소드를 정의 한 후 toString 메소드를 정의한다. 하지만 프로젝트가 커지면 커질수록 위에 말한 변수 , 메소드들이 기하급수적으로 늘어날 것이고, 늘어나면 늘어날 수록 추가도 귀찮을 뿐더러 관리도 힘들어져 결국에는 유지보수가 힘들어진다.위의 문제를 타파한 라이브러리가 Lombok이다.

Lombok은 편리성을 제공하는 라이브러리일수록 주의할 사항으로 API 설명과 내부 동작을 어느정도 숙지하고 사용해야 한다.


@Data 사용 지양

@Data@ToString, @EqualsAndHashCode, @Getter, @Setter, @RequiredArgsConstructor을 모두 포함하는 강력한 어노테이션이다. 강력한 어노테이션인 만큼 그에 따른 부작용도 많다.

@Data 사용으로 인해 발생할 수 있는 문제들을 확인해보자.

  1. 무분별한 Setter 남용 Setter는 그 의도가 분명하지 않고 객체를 언제든지 변경할 수 있는 상태가 되어서 객체의 안전성이 보장받기 힘들다.

불필요한 변경 포인트를 제공하지 않음으로써 안정성을 취할 수 있다.

  1. @ToString : 양방향 연관관계 시 순환 참조 Member 와 Coupon 이 1:N 양방향으로 매핑되어 있는 상황을 가정할 수 있다.

이때, ToString()을 호출하면 무한 순환 참조가 발생한다.

이러한 문제를 해결하기 위해서는 @ToString(exclude = "coupons") 처럼 어노테이션을 사용해서 특정 항목을 제외시키는 방법을 사용할 수 있다.

  1. @EqualsAndHashCode @EqualsAndHashCode는 상당히 고품질의 euqals()hashCode() 메소드를 만들어준다. 따라서 잘 사용하면 좋지만, 남발하면 심각한 문제가 생긴다.

특히 문제가 되는 점은 Mutable 객체에 아무런 파라미터 없이 그냥 사용하는 경우이다.

@EqualsAndHashCode
public static class Order {
    private Long orderId;
    private long orderPrice;
    private long cancelPrice;
    public Order(Long orderId, long orderPrice, long cancelPrice) {
        this.orderId = orderId;
        this.orderPrice = orderPrice;
        this.cancelPrice = cancelPrice;
    }
}
Order order = new Order(1000L, 19800L, 0L);
Set<Order> orders = new HashSet<>();
orders.add(order); // Set에 객체 추가
System.out.println("변경전 : " + orders.contains(order)); // true
order.setCancelPrice(5000L); // cancelPrice 값 변경
System.out.println("변경후 : " + orders.contains(order)); // false

위와 같이 동일한 객체여도 필드 값을 변경시키면 hashCode가 변경되면서 찾을 수 없는 값이 되버린다.

핵심은, 어노테이션 자체의 문제라기 보다는 변경 가능한 필드에 이를 남발함으로써 생기는 문제이다.

(참고 : https://www.nowwatersblog.com/springboot/springstudy/lombok)