스프링 MVC 1편 - 상품도메인개발 에서 @Data는 예측할 수 없게 동작할 수 있기 때문에 사용을 지양하고 필요한 것만 분리해서 사용하라고 하셨다.
이때 @Data의 사용을 지양 해야 되는 이유는 무엇일까?
@Data는 Lombok 라이브러리에 있는 어노테이션으로 총 5가지의 어노테이션 설정을 포함하고 있다.
Lombok
기본적으로 웹 애플리케이션에서 사용하는 VO 객체는 DB 테이블의 column 과 같은 이름의 private 변수를 가지고, getter setter 메소드를 정의 한 후 toString 메소드를 정의한다. 하지만 프로젝트가 커지면 커질수록 위에 말한 변수 , 메소드들이 기하급수적으로 늘어날 것이고, 늘어나면 늘어날 수록 추가도 귀찮을 뿐더러 관리도 힘들어져 결국에는 유지보수가 힘들어진다.위의 문제를 타파한 라이브러리가 Lombok이다.
@ToStringtoString() 메소드를 생성한다. @ToString(exclude={“제외값”})으로 제외시키고 싶은 값을 설정할 수 있다.
@Getter , @Settergetter()setter() 메소드를 생성한다.
@EqualsAndHashCodeequals(), hashCode() 메소드를 생성한다.
@RequiredArgsConstructor모든 멤버 변수를 초기화시키는 생성자를 생성한다.
@Data위에 언급한 5가지 어노테이션 설정을 모두 포함한다.
Lombok은 편리성을 제공하는 라이브러리일수록 주의할 사항으로 API 설명과 내부 동작을 어느정도 숙지하고 사용해야 한다.
@Data 사용 지양
@Data 는 @ToString, @EqualsAndHashCode, @Getter, @Setter, @RequiredArgsConstructor을 모두 포함하는 강력한 어노테이션이다. 강력한 어노테이션인 만큼 그에 따른 부작용도 많다.
@Data 사용으로 인해 발생할 수 있는 문제들을 확인해보자.
무분별한 Setter 남용
Setter는 그 의도가 분명하지 않고 객체를 언제든지 변경할 수 있는 상태가 되어서 객체의 안전성이 보장받기 힘들다.
불필요한 변경 포인트를 제공하지 않음으로써 안정성을 취할 수 있다.
@ToString : 양방향 연관관계 시 순환 참조
Member 와 Coupon 이 1:N 양방향으로 매핑되어 있는 상황을 가정할 수 있다.
이때, ToString()을 호출하면 무한 순환 참조가 발생한다.
이러한 문제를 해결하기 위해서는 @ToString(exclude = "coupons") 처럼 어노테이션을 사용해서 특정 항목을 제외시키는 방법을 사용할 수 있다.
@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가 변경되면서 찾을 수 없는 값이 되버린다.
핵심은, 어노테이션 자체의 문제라기 보다는 변경 가능한 필드에 이를 남발함으로써 생기는 문제이다.
Immutable 클래스를 제외하고는 아무 파라미터 없는 @EqualsAndHashCode 사용은 지양한다.
항상 @EqualsAndHashCode(of={“필드명시”}) 형태로 동등성 비교에 필요한 필드를 명시하는 형태로 사용한다.
실무에서는 누군가는 이에 대해 실수하기 마련인지라 차라리 사용을 완전히 금지시키고, 꼭 필요한 필드를 지정하는 것이 나을 수도 있다.
스프링 MVC 1편 - 상품도메인개발 에서
@Data
는 예측할 수 없게 동작할 수 있기 때문에 사용을 지양하고 필요한 것만 분리해서 사용하라고 하셨다. 이때@Data
의 사용을 지양 해야 되는 이유는 무엇일까?@Data
는 Lombok 라이브러리에 있는 어노테이션으로 총 5가지의 어노테이션 설정을 포함하고 있다.Lombok
기본적으로 웹 애플리케이션에서 사용하는 VO 객체는 DB 테이블의 column 과 같은 이름의 private 변수를 가지고, getter setter 메소드를 정의 한 후 toString 메소드를 정의한다. 하지만 프로젝트가 커지면 커질수록 위에 말한 변수 , 메소드들이 기하급수적으로 늘어날 것이고, 늘어나면 늘어날 수록 추가도 귀찮을 뿐더러 관리도 힘들어져 결국에는 유지보수가 힘들어진다.위의 문제를 타파한 라이브러리가 Lombok이다.
@ToStringtoString()
메소드를 생성한다.@ToString(exclude={“제외값”})
으로 제외시키고 싶은 값을 설정할 수 있다.@Getter
,@Settergetter()
setter()
메소드를 생성한다.@EqualsAndHashCodeequals()
,hashCode()
메소드를 생성한다.@RequiredArgsConstructor
모든 멤버 변수를 초기화시키는 생성자를 생성한다.@Data
위에 언급한 5가지 어노테이션 설정을 모두 포함한다.Lombok은 편리성을 제공하는 라이브러리일수록 주의할 사항으로 API 설명과 내부 동작을 어느정도 숙지하고 사용해야 한다.
@Data
사용 지양@Data
는@ToString
,@EqualsAndHashCode
,@Getter
,@Setter
,@RequiredArgsConstructor
을 모두 포함하는 강력한 어노테이션이다. 강력한 어노테이션인 만큼 그에 따른 부작용도 많다.@Data 사용으로 인해 발생할 수 있는 문제들을 확인해보자.
불필요한 변경 포인트를 제공하지 않음으로써 안정성을 취할 수 있다.
@ToString
: 양방향 연관관계 시 순환 참조 Member 와 Coupon 이 1:N 양방향으로 매핑되어 있는 상황을 가정할 수 있다.이때,
ToString()
을 호출하면 무한 순환 참조가 발생한다.이러한 문제를 해결하기 위해서는
@ToString(exclude = "coupons")
처럼 어노테이션을 사용해서 특정 항목을 제외시키는 방법을 사용할 수 있다.@EqualsAndHashCode
@EqualsAndHashCode
는 상당히 고품질의euqals()
와hashCode()
메소드를 만들어준다. 따라서 잘 사용하면 좋지만, 남발하면 심각한 문제가 생긴다.특히 문제가 되는 점은 Mutable 객체에 아무런 파라미터 없이 그냥 사용하는 경우이다.
위와 같이 동일한 객체여도 필드 값을 변경시키면 hashCode가 변경되면서 찾을 수 없는 값이 되버린다.
핵심은, 어노테이션 자체의 문제라기 보다는 변경 가능한 필드에 이를 남발함으로써 생기는 문제이다.
@EqualsAndHashCode
사용은 지양한다.@EqualsAndHashCode(of={“필드명시”})
형태로 동등성 비교에 필요한 필드를 명시하는 형태로 사용한다.(참고 : https://www.nowwatersblog.com/springboot/springstudy/lombok)