# 35. ordinal 메서드 대신 인스턴스 필드를 사용하라

***

## ✅ 1. ordinal()이란?

> `ordinal()`은 enum 상수가 \*\*정의된 순서(0부터)\*\*에 따라 자동 부여되는 번호를 반환하는 메서드

```java
enum Day {
    MONDAY, TUESDAY, WEDNESDAY;
}

Day.MONDAY.ordinal();    // 0
Day.TUESDAY.ordinal();   // 1
```

* enum이 자동으로 제공하는 메서드
* 상수 정의 순서에 의존하는 숫자

***

## ✅ 2. 왜 사람들이 `ordinal()`을 쓰고 싶어할까?

> 숫자 값이 필요할 때, 간단히 `ordinal()`을 쓰면 편해 보이기 때문

### 예: 연주자 수 표현

```java
public enum Ensemble {
    SOLO, DUET, TRIO, QUARTET;
    
    public int numberOfMusicians() {
        return ordinal() + 1;
    }
}
```

* `SOLO → 0 + 1 = 1명`
* `DUET → 1 + 1 = 2명`

> ✅ 처음엔 잘 동작하지만, **큰 함정이 숨어 있음**

***

## ❌ 3. ordinal()의 위험성

### 🧨 문제 1: 선언 순서가 바뀌면 결과가 깨진다

```java
public enum Ensemble {
    SOLO, DUET, TRIO;
}
```

→ `DUET.ordinal() == 1`

```java
// 나중에 순서 바꿈
public enum Ensemble {
    DUET, SOLO, TRIO;
}
```

→ `DUET.ordinal() == 0` ❗\
→ **결과가 바뀌어버림!**

***

### 🧨 문제 2: 중간값을 비워둘 수 없음

```java
public enum Ensemble {
    SOLO, DUET, TRIO, ..., DECTET, TRIPLE_QUARTET;

    public int numberOfMusicians() {
        return ordinal() + 1;
    }
}
```

* `TRIPLE_QUARTET.ordinal() = 11 → 12명`
* 그런데 나중에 `ELEVEN_TET`(11명)를 추가하면?
* 중간에 끼워야 하므로 **순서가 깨지고** 로직이 오동작함

***

### 🧨 문제 3: 같은 값을 가진 다른 이름 표현 불가

* `OCTET`도 8명
* `DOUBLE_QUARTET`도 8명

```java
OCTET.ordinal() = 7 → 8명
DOUBLE_QUARTET.ordinal() = 8 → 9명 ❌
```

> → `ordinal()` 값이 달라서, **같은 의미의 상수를 표현할 수 없음**

***

## ✅ 4. 해결책: 명시적인 필드를 사용하자

```java
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),
    ELEVEN_TET(11), TRIPLE_QUARTET(12);

    private final int musicians;

    Ensemble(int musicians) {
        this.musicians = musicians;
    }

    public int numberOfMusicians() {
        return musicians;
    }
}
```

***

### ✅ 장점

| 문제      | ordinal 방식  | 필드 방식     |
| ------- | ----------- | --------- |
| 순서 바뀜   | ❌ 값도 바뀜     | ✅ 값 고정    |
| 중간 값 없음 | ❌ 강제로 더미 추가 | ✅ 자유롭게 비움 |
| 같은 값 표현 | ❌ 불가능       | ✅ 가능      |
| 유지보수    | ❌ 위험        | ✅ 안전하고 명확 |

***

## ✅ 5. 요약

> `ordinal()`은 enum 내부의 **순서를 위한 유틸 메서드일 뿐**,\
> 그 값을 의미 있는 로직에 사용하는 것은 매우 위험한 습관입니다.

✅ 대신, 의미 있는 값은 **명시적인 인스턴스 필드**로 정의하세요.

***

> `ordinal()`은 편해 보이지만, 로직에서 쓰면 쉽게 깨지는 폭탄 같은 존재입니다.\
> 진짜 의미 있는 숫자는 필드에 직접 저장하는 게 안전합니다.

***

**발표 자료**

<https://byumm315.atlassian.net/wiki/external/MWJkNjhmOGI4NWM1NDFhYmFmMDQ0YzBkZDY5ZWE0ODg>
