Spring - Lombok

우야·2021년 7월 9일
0

사용시 중의 사항

실무 프로젝트에서는 보수적으로 사용

  1. 개인 Toy 프로젝트가 아닌 실무 프로젝트에서는 가급적 @Getter, @Setter, @ToString 만 사용하고 그 외의 것들 사용은 자제하거나 매뉴얼을 잘 읽어보고서 보수적으로 사용하는게 좋다.

  2. @EqualsAndHashCode는 Immutable 필드만 명시적으로 지정하면서 자제해서 사용하거나 가급적 IDE 코드 제너레이션등을 통해 코드를 직접 만든다.

  3. 특히 Experimental 기능은 사용하지 말고, IDE 지원이 확실치 못하고 문법 파괴적인 val도 사용하지 않는 것이 좋을 것 같다.

lombok.config를 사용해 각종 Annotation 사용금지 하게 할수 잇음

  • @Data, @Value, val, @NonNull, @AllArgsConstructor, @RequiredArgsConstructor를 사용금지 하게 하여 컴파일 오류를 발생기키게 할수 있음
config.stopBubbling = true
lombok.data.flagUsage=error
lombok.value.flagUsage=error
lombok.val.flagUsage=error
lombok.var.flagUsage=error
lombok.nonNull.flagUsage=error
lombok.allArgsConstructor.flagUsage=error
lombok.requiredArgsConstructor.flagUsage=error
lombok.cleanup.flagUsage=error
lombok.sneakyThrows.flagUsage=error
lombok.synchronized.flagUsage=error
# experimental 전체 금지
lombok.experimental.flagUsage=error

# 기타 각종 사용해서는 안되는 기능들을 모두 나열할 것.

왜 이렇게 사용을 조심해야 하나?

1. @AllArgsConstructor, @RequiredArgsConstructor 사용금지
매우 편리하게 생성자를 만들어주지만 개발자의 별 생각없는 꼼꼼함이 치명적 버그가 되게 만들 수 있다.

//모든 매개변수를 가지는 생성자를 자동으로만들어줌
@AllArgsConstructor
public static class Order {
    private long cancelPrice;
    private long orderPrice;
}
 
// 취소금액 5,000원, 주문금액 10,000원
Order order = new Order(5000L, 10000L); 

아래와 같이 리팩토링을 해버리면!!!!!

@AllArgsConstructor
public static class Order {
    private long orderPrice;
    private long cancelPrice;
}


// 사용하는 부분에서 이코드들을 안바꿔준다면!!!
/// 원래 취소금액 5,000원, 주문금액 10,000원이였지면, 리팩토링으로 완전 주문이 5000원 취소가 10000원이 되어 버리는 문제가 발생될수 있음
Order order = new Order(5000L, 10000L); 

대안 : 이런 경우를 위해 Builder를 사용할 수 있음

public static class Order {
    private long cancelPrice;
    private long orderPrice;
 
    @Builder
    private Order(long cancelPrice, long orderPrice) {
        this.cancelPrice = cancelPrice;
        this.orderPrice = orderPrice;
    }
}
 
// 필드 순서를 변경해도 문제 없음.
Order order = Order.builder().cancelPrice(5000L).orderPrice(10000L).build();
System.out.println(order);

2. 무분별한 @EqualsAndHashCode 사용 자제

  • @EqualsAndHashCode는 상당히 고품질의 equals, hashCode 메소드를 만들어준다.
  • Mutable(변경가능한) 객체에 아무런 파라미터 없이 그냥 사용하는 @EqualsAndHashCode 애노테이션
@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

동일한 객체임이도 Set 에 저장한 뒤에 필드 값을 변경하면 hashCode가 변경되면서 찾을 수 없게 되어버린다.

대안 : @EqualsAndHashCode(of={“필드명시”})
1. 동등성 비교에 필요한 필드를 명시하는 형태로 사용하는게 좋다.
2. Java equals & hashCode 좋은 equals 만드는 방법

3. @Data 사용금지

  • @EqualsAndHashCode와 @RequiredArgsConstructor 등을 포함하는 Mutable한 데이터 클래스를 만들어주는 조합형 애노테이션이다.
  • @EqualsAndHashCode와 @RequiredArgsConstructor를 포함하기 때문에 사용을 아예 금지

대안 : @Getter, @Setter, @ToString 사용

@Getter
@Setter
@ToString
public class Order {
...
    // 생성자와 필요한 경우에만 equals, hashCode 직접 작성
}

4. @Value 사용금지

  • Immutable 클래스를 만들어주는 조합 애노테이션이지만 이 또한 @EqualsAndHashCode, @AllArgsConstructor 를 포함
  • @EqualsAndHashCode는 불변 클래스라 큰 문제가 안되지만 @AllArgsConstructor가 문제가 됨

대안 : @Getter, @ToString 사용

@Getter
@ToString
public class Order {
   // private final 로 여러 필드 생성
    // 생성자와 필요한 경우에만 equals, hashCode 직접 작성
}

5. Log 자제

  • 가급적이면 @Slf4j만 사용하고 나머지는 사용할 수 없게 금지시키는 것도 가능

6. NonNull 사용 금지

  • 사실 개인적 취향에 가까운데, 불필요하게 branch coverage를 증가시키기 때문

7. @ToString, @EqualsAndHashCode 필드명 지정시 오타 문제

  • 필드, 혹은 메소드에 Include, Exclude 지정이 가능
  • 문제는 이게 필드 이름을 String으로 지정하기때문에, IDE 에서 필드명을 리팩토링할 때 올바로 반영이 안되거나, 아주 단순한 오타가 나도 눈치를 못 챌 수 있음
profile
Fullstack developer

0개의 댓글