본문 바로가기
java || spring boot

Java에서 Enum + Bitmask 패턴 활용하기

by 정구지개발자 2025. 2. 10.
728x90
## 2. Bitmask만 사용한 경우 (가독성 낮음)
Bitmask를 활용하면 여러 상태를 비트 연산(OR, AND 등)을 통해 효율적으로 관리할 수 있습니다.

```java
public class BitmaskExample {
    // 권한을 나타내는 비트 마스크 값 정의
    public static final int FLAG_READ = 1 << 0;   // 0001
    public static final int FLAG_WRITE = 1 << 1;  // 0010
    public static final int FLAG_EXECUTE = 1 << 2;// 0100

    public static void main(String[] args) {
        int permission = FLAG_READ | FLAG_WRITE; // 0011 (READ + WRITE)

        // 특정 권한이 있는지 확인
        if ((permission & FLAG_READ) != 0) {
            System.out.println("읽기 권한 있음");
        }
        if ((permission & FLAG_WRITE) != 0) {
            System.out.println("쓰기 권한 있음");
        }
        if ((permission & FLAG_EXECUTE) != 0) {
            System.out.println("실행 권한 있음");
        }
    }
}
```

### 🔴 문제점
- FLAG_READ, FLAG_WRITE 같은 숫자로만 관리하면 각 상태의 의미가 직관적이지 않음.
- 여러 개의 비트 연산이 많아지면 코드 가독성이 떨어지고 유지보수가 어려워짐.
- 비트 연산이 익숙하지 않은 사람들에게는 이해하기 어려움.

---

## 3. Enum + Bitmask 패턴 (가독성 개선)
Bitmask의 성능을 활용하면서도, Enum을 사용하여 각 상태의 의미를 명확하게 표현할 수 있습니다.

```java
public class EnumBitmaskExample {
    // Enum을 사용해 각 상태를 명확하게 정의
    public enum Permission {
        READ(1 << 0),    // 0001
        WRITE(1 << 1),   // 0010
        EXECUTE(1 << 2); // 0100

        private final int mask;

        Permission(int mask) {
            this.mask = mask;
        }

        public int getMask() {
            return mask;
        }
    }

    public static void main(String[] args) {
        int permission = Permission.READ.getMask() | Permission.WRITE.getMask(); // 0011 (READ + WRITE)

        checkPermission(permission, Permission.READ);
        checkPermission(permission, Permission.WRITE);
        checkPermission(permission, Permission.EXECUTE);
    }

    public static void checkPermission(int permission, Permission flag) {
        if ((permission & flag.getMask()) != 0) {
            System.out.println(flag + " 권한 있음");
        } else {
            System.out.println(flag + " 권한 없음");
        }
    }
}
```

### ✅ 개선된 점
- Permission.READ처럼 의미를 명확하게 표현할 수 있어 가독성이 향상됨.
- getMask()를 통해 Bitmask 값에 접근할 수 있어 코드 유지보수가 쉬워짐.
- 기존의 Bitmask 방식보다 직관적인 코드 작성이 가능.

---

## 4. EnumSet을 활용한 대체 방법 (더 깔끔한 코드)
Java에서는 EnumSet을 활용하면 Bitmask 연산 없이도 여러 상태를 쉽게 관리할 수 있습니다.
EnumSet은 내부적으로 비트 연산을 활용하지만, 코드가 훨씬 직관적입니다.

```java
import java.util.EnumSet;

public class EnumSetExample {
    public enum Permission {
        READ, WRITE, EXECUTE
    }

    public static void main(String[] args) {
        EnumSet<Permission> permissions = EnumSet.of(Permission.READ, Permission.WRITE);

        checkPermission(permissions, Permission.READ);
        checkPermission(permissions, Permission.WRITE);
        checkPermission(permissions, Permission.EXECUTE);
    }

    public static void checkPermission(EnumSet<Permission> permissions, Permission flag) {
        if (permissions.contains(flag)) {
            System.out.println(flag + " 권한 있음");
        } else {
            System.out.println(flag + " 권한 없음");
        }
    }
}
```

### ✅ EnumSet의 장점
- EnumSet.of(Permission.READ, Permission.WRITE)처럼 여러 상태를 직관적으로 추가 가능.
- contains(flag) 메서드로 비트 연산 없이도 상태 체크 가능.
- Bitmask의 복잡한 비트 연산을 사용하지 않아 가독성과 유지보수성이 뛰어남.

---

## 5. Enum + Bitmask vs EnumSet 비교

| 방식 | 장점 | 단점 | 추천 상황 |
|------|------|------|-----------|
| **Enum + Bitmask** | 메모리 절약, 빠른 연산 속도 (비트 연산) | 코드가 복잡해질 수 있음, 가독성↓ | **성능이 중요한 경우 (최적화 필요)** |
| **EnumSet** | 가독성↑, 유지보수 쉬움 | 내부적으로 비트 연산을 사용하지만, 메모리 최적화는 Bitmask보다 부족할 수 있음 | **일반적인 상태 관리 (대부분의 경우 추천)** |

---

## 6. 결론
### ✅ Bitmask가 필요할 때
- 성능 최적화가 중요할 경우 (Bitmask 연산은 메모리를 절약하고 연산 속도가 빠름).
- 수십 개 이상의 상태를 관리해야 할 때.
- 기존 Bitmask 기반 코드와의 호환성이 필요할 때.

### ✅ EnumSet이 적절할 때
- 가독성과 유지보수성이 중요한 경우 (대부분의 애플리케이션에서 권장).
- 상태의 개수가 적고, 상태 변경이 빈번하지 않을 때.
- Bitmask 연산이 필요하지 않은 경우.



728x90

'java || spring boot' 카테고리의 다른 글

추상이란?  (0) 2025.02.22
유용한 intellj 단축키  (0) 2025.02.18
BitSet 이란? in java  (4) 2025.02.03
묵시적형변환이란?  (1) 2025.01.16
API 요청 하기 restTemplate 사용  (0) 2024.05.10

댓글