🧶 '프로그래머스 데브코스 4기 백엔드'에서 진행한 <네이버 웹툰 클론코딩> 팀 프로젝트 기록입니다.
부제: 이용 연령 등급 Enum으로 개선하기
이 포스팅은 네이버 웹툰을 클론코딩하면서 '이용 연령 등급' 데이터에 enum 클래스를 적용함으로써 코드를 개선한 과정에 대한 이야기이다. 특히 이번 편은 어떤 기술보다는 설계에 관해서 했던 잡생각들에 대해 쓰려고 한다.
솔직히 말해서 이전에는 enum이랑 별로 안 친했다.
지금 보면 '아니 이걸 enum 안 쓰면 어디에 써...?'라고 생각한다. 그리고 이 글을 보는 누구든 그렇게 생각할 것 같다. 결과적으로는 후술할 생각과 시행착오를 거쳐 enum과 아주 친해졌고 코드 개선에 알차게 사용할 수 있게 되었다.
서비스 분석
네이버 웹툰에서 웹툰 상세 정보를 살펴보자.
제목, 작가, 썸네일, 연재 요일, 연령 등급, 줄거리, 해시태그 등이 있다.
일단 연재 요일의 경우 java.time.DayOfWeek
을 이용했다. DayOfWeek
은 이름에서 알 수 있듯이 요일에 대한 enum 클래스이고, 코드를 살펴보면 날짜 계산에 유용하게 사용할 수 있다는 것을 알 수 있다. 아무튼 기본으로 제공되는 enum 클래스를 이용했으니, '연재 요일'에 대해서는 생략하고 바로 '이용 연령 등급'으로 넘어가겠다.
우리가 분석해 본 바에 의하면, 네이버 웹툰은 '18세 이용가' 웹툰에 대해서만 인증을 요구한다. 그 외 등급에 대해서는 고지만 할 뿐, 별다른 인증 절차를 요구하지 않는다. 그래서 성인이용가에 대해서만 '로그인하지 않은 사용자의 접근'과 '로그인을 했으나 미성년자인 회원의 접근'에 제한을 두기로 요구사항을 작성했다.
그렇다면 이 웹툰이 '18세이용가'인지 아닌지만 알면 되는 것 아닌가?!
enum 안 쓰고 어떻게 하려고 했는데?
그래서 처음에는 Webtoon 엔티티 안에 필드로
- boolean 타입의
isXRated
두기 - short 타입의
ageLimit
두기
두 방법을 생각했다. 참고로 'XRated'란 '미성년자 관람 불가'를 의미한다.
하지만 위에서 볼 수 있듯이, 실제 서비스에선 상세 정보에 연령 등급을 정확하게 표기하고 있다. 또한 요구사항 변경이나 확장성을 고려해서 boolean 타입의 isXRated
필드를 두는 방법은 바로 탈락시켰다.
그 다음엔 아래처럼 short 타입의 ageLimit
필드를 둬 봤다.
@Column(name = "age_limit", nullable = false)
private short ageLimit;
이 경우 연령 제한과 사용자의 나이를 비교하는 과정은 아주 쉬워질 것이다. 하지만 사용자의 나이를 성인 기준 나이와 비교하는 과정이 또 필요하다. 성인 기준 나이를 매직 넘버로 두면 유지보수 측면에서 최악일 것이다. 그렇다고 성인 기준 나이를 상수로 두자니 어디에 둘지 애매해진다.
그래서 왜 enum을 쓰기로 결정했냐면...
내가 원했던 것을 다시 정리하자면 다음과 같다.
- 정책상 성인 기준 나이가 변경되어도 유지보수가 쉬워야 한다.
- 연령 제한과 사용자의 나이 비교와 사용자의 나이와 성인 기준 나이 비교 모두 깔끔하게 구현할 수 있어야 한다.
그리고 결정적으로! 도메인과 객체의 관점에서, Webtoon
인스턴스는 제한을 두는 나이의 '숫자'가 아니라, 정책상 '등급'을 가지고 있어야 한다고 생각했다. 그래서 필드명도 ageLimit
이 아니라 ageRating
으로 냅다 바꿔 버렸다.
AgeRating enum Ver.1
그렇게 처음 만든 이용 연령 등급 enum 클래스는 아래와 같았다.
@Getter
public enum AgeRating {
ALL(0), // 전체연령가
OVER_12(12), // 12세이용가
OVER_15(15), // 15세이용가
OVER_18(18); // 18세이용가
private final int ageLimit;
AgeRating(int ageLimit) {
this.ageLimit = ageLimit;
}
}
각 등급은 등급의 기준 나이를 ageLimit
으로 갖는다.
원래는 각 연령 등급을 G_RATED
, PG_12
, PG_15
, X_RATED
로 지었는데, 미국 등급이라 코드 가독성이 영 좋지 못해서 리뷰를 받아 ALL
, OVER_12
, OVER_15
, OVER_18
로 결정했다.
하지만 이 또한 마음에 쏙 든 것은 아니었는데.. 이에 대해서는 다음 포스팅에서 서술하겠다.