Enum을 조금 더 잘 활용하는 방법

안상철·2023년 1월 7일
0

이모저모개발

목록 보기
8/8

참고: https://techblog.woowahan.com/2527/

Enum은 자바에 새로 추가된 열거형이라는 서로 연관된 상수의 집합이다.
DB 테이블의 상태관리나 flag컬럼, RoleType 지정 등 여러부분에서 사용되고 있다.

Enum을 조금 더 똑똑하게 사용하는 방법이 구현되어 있어서 기록 해 두려고 한다.

1. EnumModel

EnumModel 인터페이스를 만들어서 Enum을 같은 형태로 지정할 수 있도록 정해놓자

interface EnumModel {
    fun getCode(): String
    fun getKorName(): String
    fun getEngName(): String
}

Enum 코드값과 한글명, 영문명을 가질 수 있도록 했고 화면에서 적재적소에 사용 할 예정이다.

2. Role을 예로 들어서

enum class Role(private val korName: String, private val engName: String) : EnumModel {

    ROLE_USER("사용자", "USER"),
    ROLE_ADMIN("관리자", "ADMIN"),
    ROLE_SYS_ADMIN("시스템관리자", "SYSTEM");

    override fun getKorName(): String {
        return korName
    }

    override fun getEngName(): String {
        return engName
    }

    override fun getCode(): String {
        return name
    }
}

EnumModel을 상속받아 구현 해 준다. 앞에는 코드, 인자로는 한글명과 영문명을 작성 해 준다.
이제 ROLE_USER와 사용자, USER는 같은 값을 가진다.

또 get~ 메서드로 원하는 곳에 원하는 값을 get해줄 수 있도록 한다.

3. EnumMapperConfig와 EnumMapper

@Configuration
class EnumMapperConfig {

    @Bean
    fun enumMapper(): EnumMapper {
        val enumMapper = EnumMapper()
        enumMapper.put("ROLE", Role::class.java)
        return enumMapper
    }
}
class EnumMapper {
    private val factory: MutableMap<String, List<EnumValue>> = HashMap<String, List<EnumValue>>()

    private fun toEnumValues(e: Class<out EnumModel>): List<EnumValue> {
        return e.enumConstants.map { EnumValue(it) }
    }

    fun put(key: String, e: Class<out EnumModel>) {
        factory[key] = toEnumValues(e)
    }

    operator fun get(keys: String): Map<String, List<EnumValue>?> {
        return keys.split(",").toTypedArray().associateWith { key: String -> factory[key] }

    }
}

다음은 enum 목록 조회시 사용할 enum 등록 해 주는 config 클래스를 만들어준다.
@Configuration 어노테이션으로 설정 클래스임을 알려주고 @Bean에 enumMapper를 등록해준다.

put 메서드는 MutableMap이라는 가변 Map에 Enum이름과 그 값들을 Map형태로 넣어줄 수 있도록 한다. get 메서드를 통해 콤마를 기준으로 Enum의 이름과 그 값들을 조회할 수 있도록 한다.

enumMapperConfig에 조회하고자 하는 EnumModel로 구현한 Enum클래스를 넣어주면

4. Controller

class CommCodeController(
    private val enumMapper: EnumMapper,
    ) {

    @Operation(summary = "enumMapper에 등록된 enum 목록 조회")
    @GetMapping("/enums/{names}")
    fun findByEnums(@PathVariable("names") names: String): ResponseEntity<Map<String, List<EnumValue>?>> {
        return ResponseEntity.ok(enumMapper[names])
    }
}
data class EnumValue(val code: String, val korName: String, val engName: String) {
    constructor(enumModel: EnumModel) : this(
        enumModel.getCode(), enumModel.getKorName(), enumModel.getEngName()
    )

이런 형태로 Enum의 이름을 넣어 Enum 값들을 조회할 수 있다.
이 예시에서는 ROLE이라는 이름을 requestParam으로 전달 해 주면, 따로 정의한 EnumValue라는 데이터 클래스에 담겨 Role 클래스에 등록된 Enum목록이 차례로 조회되어 나온다.

profile
웹 개발자(FE / BE) anna입니다.

0개의 댓글