Learn business/Java

Enum과 Generic 함께 사용하기


개요

코드를 단순하게 만들면서 가독성을 높히기 위한 개발을 하다보면 Enum 타입을 사용하는 것은 흔하게 일어납니다. 또한 if / else 문 사용을 지양하는 방향으로 코드를 만들다 보면 Enum 클래스에 추상 메소드나 인터페이스를 구현하는 일도 마주하게 될 것입니다. 저 역시 조금 더 클린한 코드를 만들기 위해 Enum 클래스를 많이 사용하는데요. 최근에 회사에서 맡은 프로젝트를 진행하면서 Enum 타입을 생성하고 인터페이스를 상속 받아서 각 타입별로 상속 받은 메소드를 구현하고 있었습니다. 그런데 Enum 타입에 정의한 상수별로 각각 다른 타입의 객체를 리턴해주고 싶은 니즈가 생겼습니다. 그 내용을 아래에 공유하고자 합니다.

 

인터페이스를 구현한 Enum 클래스

ViewAreaBanner 인터페이스를 상속받은 ViewAreaType의 Enum 타입이 있습니다. ViewAreaType의 Enum 클래스에는 GNB_LOGO_IMG / GNB_BANNER_IMG 라는 2가지 상수를 정의하고 있습니다. 그리고 ViewAreaBanner 인터페이스에 getValue(ViewArea viewArea) 라는 메소드를 정의하여 ViewAreaType에 정의된 상수별로 각각에 맞는 값을 가져오도록 하는게 목적입니다. 값은 파라미터로 넘어온 viewArea 객체 안에 정의되어 있으며 각 타입에 맞는 값을 찾아 반환하면 됩니다.  각각의 코드는 아래와 같습니다.

 

 

추가되는 스펙

깔끔하게 Enum을 통해서 각 상황에 맞는 상수를 정의하고 인터페이스를 상속하여 각 타입 별로 상황에 맞는 값을 반환하도록 하였습니다. 만약 새로운 상수가 추가되면 똑같이 ViewAreaType의 Enum 클래스에 상수를 추가 및 구현해주면 될 것입니다. 그런데 이번엔 조금 특이한 스펙이 들어왔는데 GNB 영역에 카테고리 구좌를 추가하는 것이었습니다. 이 카테고리 영역 역시 ViewArea에 정의되어 있으나 기존과 다른 점은 String 타입이 아니라 List<String> 타입으로 반환해야한다는 점이었습니다.

 

인터페이스를 Generic 타입으로 변경

사실 Generic과 Enum 타입은 서로 공존할 수 없습니다. 왜냐하면 Enum은 고정된 상수 값으로 컴파일 시점에 정의됩니다. 반면 Generic은 런타임 시점에서 그 타입이 결정됩니다. 따라서 Enum 타입의 클래스에 Generic 인터페이스를 상속받아 컴파일 하면 특별히 Generic  Parameterized Type에 제한을 두지 않으면 컴파일 시점에 Object로 변환될 것입니다. 이러한 속성을 이용하여 각 Enum 타입의 각각의 상수별로 다른 타입을 반환하도록 작업하였습니다. 

 

아래와 같이 ViewAreaBanner 인터페이스를 Generic 인터페이스로 변경합니다.

 

그리고 Enum 클래스에 ViewAreaBanner 인터페이스를 상속받아서 재구현해주면 String 반환타입이 Object로 변경된다는 것을 볼 수 있습니다. 사실상 Object는 모든 클래스의 최상위 클래스이기 때문에 Enum 클래스의 각각의 상수가 반환하는 타입으로 변환해도 컴파일 에러가 발생하지 않습니다.

 

정리

이렇게 Enum 타입에 스펙에 맞는 상수를 정의하고, 각각의 상수의 역할을 인터페이스로 정의하여 구현하였습니다. 더 나아가 각각의 상수가 서로 다른 타입을 반환해야할 때 Generic 인터페이스를 도입하여 구현하는 방법도 알아봤습니다. 조금 더 알아보니까 Genric과 Enum에 관련하여 Enhanced Enums라는 것이 JEP 문서에 제안되었다는 걸 찾았는데(링크) 아직 받아들여지지 않은 것 같습니다. 추후에 좀 더 공부해보는 것이 좋을 것 같습니다.

'Learn business > Java' 카테고리의 다른 글

자바 클래스패스  (1) 2020.03.31
[5편] 제네릭이란?  (3) 2020.01.05
[4편] 제네릭이란?  (1) 2020.01.05
[3편] 제네릭이란?  (1) 2019.11.02
[2편] 제네릭이란?  (0) 2019.11.02