- [Effective Java] 6장 열거 타입과 애너테이션
- [Java] Enum to Json / Enum to Object
- https://woowabros.github.io/tools/2017/07/10/java-enum-uses.html
enum을 쓰기 전에 체크해봐야 할 것
enum을 쓰든, DB 코드 테이블을 참조하든 둘 중 하나만 하는 것이 좋다.
예를 들어, 아래 예제 코드에서 code 1 : 현금, 2 : 카드 라는 정보가 DB의 "결제 코드" 테이블에 이미 있다면?
- 관리 포인트가 늘어난다. 수정 사항이 발생했을 때 DB에도, enum에도 둘 다 반영해야 한다.
- 매번 DB에서 읽어오는게 부담이라면?
- DBMS function을 이용해 코드 변환 (매번 조인보다 낫다)
- redis에 코드 테이블 올려두고 사용하는 방법
- 객체 내부에 Holder를 두어 같은 내용으로 두 번 resolve 하지 않도록 캐시처럼 사용하는 방법
- 하지만 이건 DB가 업데이트 되면 캐시도 업데이트 해주어야 한다는 문제점이 있어 좋지 않다.
- DB에 있는 코드 표를 enum으로 아예 옮겨버리는 방법 (배민 enum 활용기)
- 하지만 enum을 만드는게 이득이 크다고 판단되면 DB에 있어도 enum도 만들 수도 있다.
- 빈번히 참조되는데 변경이 자주 일어나지 않는 경우..?
enum도 결국 소스코드이기 때문에, 변경이 발생한다면 다시 컴파일해야 한다.
- 컴파일 시간이 굉장히 오래 걸린다면 장점이 있겠지만 보통의 경우는 글쎄.
- 상수 값이 자주 변경된다면, `` .yml, .properties``같이 외부로 빼면 컴파일 없이 jar 패키징만 해도 적용 가능하다.
- spring에서 .properties에 있는 값을 enum에 세팅하려면?
enum은 extends는 불가하지만, implements는 가능하다.
- 공통 interface를 만들 때는, getter의 선언부가 인터페이스에 들어가줘야 해당 인터페이스 타입으로 접근했을 때 .getCode() 같은 메서드를 호출할 수 있다. (클래스 구현부에서는 @Getter를 써도 된다.)
예제
```java
// Getter가 정의되어 있어야 .getCode()같은 것으로 내부 값을 가져올 수 있다. interface를 쓰는 경우는 추가적으로 인터페이스 쪽에 getter를 선언해야 할 수 있다.
@Getter
@RequiredArgsConstructor
public enum PaymentCode {
CASH(1, "현금", "cash"), // 여기서 세번째 인자는 별로 필요없지만 이렇게도 가능하다는 것을 보여주기 위해.
CARD(2, "카드", "card");
private final int code;
private final String koName;
private final String enName;
public static PaymentCode fromKoName(String text){
for (PaymentCode code :values()){
if (code.getKoName().equals(text)) {
return code;
}
}
throw new IllegalArgumentException();
}
}
```
```java
/**
* 위 코드와는 관련 없지만 함수형으로 쓰면 이런 식이 된다.
*/
public static PaycoResponseCode from(int _code) {
return Stream.of(values())
.filter(responseCode -> responseCode.getCode() == _code)
.findAny()
.orElseThrow(NoSuchElementException::new);
}
```
- 위 방식은 매번 호출할 때 마다 for나 stream을 돌게 되는데, Map으로 key-value를 미리 저장해 두고 거기서 꺼내는 식으로 해도 좋다.
- enum.values()가 매번 호출되는 것을 막기 위해 enum factory를 사용하거나, static 변수에 이를 담아두는 경우가 있는데, 굳이 그럴 필요 까지는 없다.
```java
/* 기본 제공 */
log.info("{}", Payment.PaymentCode.valueOf("CARD")); // CARD 아래와 같다. 이름 문자열 받아서 enum찾을 때 말고는 쓸일 없는 듯.
log.info("{}", Payment.PaymentCode.CARD); // CARD 위와 같다.
log.info("{}", Payment.PaymentCode.CARD.name()); // CARD
// Payment.PaymentCode.values() 이 것도 있다.
/* @Getter */
log.info("{}", Payment.PaymentCode.CARD.getEnName()); // card
log.info("{}", Payment.PaymentCode.CARD.getKoName()); // 카드
log.info("{}", Payment.PaymentCode.CARD.getCode()); // 2
/* 직접 정의. */
log.info("{}", Payment.PaymentCode.fromKoName("현금")); // CASH
```
'Languages & Frameworks > Java' 카테고리의 다른 글
[Effective Java] 3장 모든 객체의 공통 메서드 (0) | 2019.12.04 |
---|---|
[Effective Java] 2장 객체 생성과 파괴 (0) | 2019.12.02 |
[java] 날짜 시간 처리 관련 (0) | 2019.07.10 |
[Java] Enum (0) | 2019.06.06 |
[Java] Stream API 노트 (0) | 2017.03.09 |
[Java] lambda 기본 개념 (0) | 2017.02.07 |