이펙티브 자바 아이템 36 ordinal 메서드 대신 인스턴스 필드를 사용하라

Sorbet·2021년 11월 6일
0

아이템 36 ordinal 메서드 대신 인스턴스 필드를 사용하라

일반적인 경우 Enum 의 Ordinal 사용은 안티패턴

public enum Ensemble {
  
  SOLO, DUET, TRIO, QUARTET, QUINTET,
  SEXTET, SEPTET, OCTET, NONET, DECTET;
  
  public int numberOfMusicians() { 
    return ordinal() + 1; 
  }
}
  • 위 코드에서 SOLO=1 부터 접근하는, 열거타입을 int형 정수로 사용하게 된다
  • 열거형을 정수로 사용하면 몇가지 문제가 발생하는데
    • 열거형의 장점을 모두 잃어버림(아이템 34)
    • 더해서 이넘>숫자는 변경이 쉬운데, 숫자> 이넘 변경은 지저분할수 밖에 없다
    • 중간에 비는값을 표현하지 못한다(3->7 못함), Dummy를 추가하면 되지만.. 코드도 지저분해지고, 실용성도 떨어진다
  • 해결책 : ordinal 사용하지 말고 인스턴스 필드에 저장하기

인스턴스 필드에 데이터 저장하기

public enum Ensemble {
  SOLO(1), DUET(2), TRIO(3), QUARTET(4), QUINTET(5),
  SEXTET(6), SEPTET(7), OCTET(8), DOUBLE_QUARTET(8),
  NONET(9), DECTET(10), TRIPLE_QUARTET(12);

  private final int numberOfMusicians;
	
  Ensemble(int size) { 
    this.numberOfMusicians = size; 
	}
	
  public int numberOfMusicians() { 
    return numberOfMusicians; 
	}
}
  • 그러니까, ordinal을 사용하고 싶다는건 Enum 을 정수 숫자형으로 쵸현하고 싶은거기ㄴ까 이렇게 하면 된다

JPA에서 Enum변수 저장시에도 Ordinal 말고 String 전략으로

  • enum 타입을 엔티티 클래스의 필드변수로 사용할때 저장하는 방식이 두가지인데 @Enumerated 애노테이션에는 EnumType으로 지정이 가능
    • EnumType.ORDINAL : enum 순서 값 숫자로 DB에 저장
    • EnumType.STRING : enum 이름을 문자열로 DB에 저장
  • Enum필드를 저장할때 기본값이 EnumType.ORDINAL 이라서 숫자로 저장된다.
    • 오디널 쓰면 안되는 이유는 앞에서 많이 다뤘으므로 생략
@Column(name = "item_sell_status", nullable = false)
@Enumerated(EnumType.STRING)
private SellStatus sellStatus;
public enum SellStatus {
    ON_SALE(1),
    OUT_OF_STOCK(2),
    SUSPENDED(5),
    END_OF_LINE(9);

    private int sellStatus;

    SellStatus(int i) {
        sellStatus = i;
    }
}
  • 이런식으로 쓰고 있습니다
@Enumerated(EnumType.STRING)
@Column(nullable = false)
private Role role;
@Getter
@RequiredArgsConstructor
public enum Role {
    GUEST("ROLE_GUEST", "손님"),
    USER("ROLE_USER", "일반사용자"),
    ADMIN("ROLE_ADMIN","관리자");

    private final String Key; //스프링 시큐리티에서는 권한 코드에 항상 ROLE_가 앞에 붙어있어야 함
    private final String title;
}
profile
Sorbet is good...!

0개의 댓글