일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | |||||
3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 |
- 백준#boj#16932#모양만들기
- 백준#BOJ#12865#평범한배낭
- 백준#BOJ#14501#퇴사#브루트포스
- 백준#boj#12755
- 백준#BOJ#1939#중량제한
- 백준#BOJ#8012#한동이는영업사원
- 백준#BOJ#2615#오목
- Today
- Total
순간을 성실히, 화려함보단 꾸준함을
어느 날 이넘(enum) 이 내게 찾아왔다! 본문
안녕하세요
오늘은 글또 7번째 글을 작성해보려고 합니다.
주제는 '어느 날 이넘(enum) 이 내게 찾아왔다!'
즉, enum 활용하여 고객의 요구사항을 구현했던 경험을 작성해보려고 합니다.
배경
어떠한 신청서를 신청하게 되면 승인/반려 처리를 하는 프로세스가 존재합니다.
이때 '반려' 처리를 하게 되면 각 신청서에 대해 반려 사유를 신청자에게 알람톡이 가게끔 기능을 개발해달라는 요구사항이 들어왔습니다.
신청서는 학자금, 리조트, 의료비 등등 다양한 유형들의 신청서들이 존재하고 있습니다.
모든 신청서관련 클래스는 공통의 추상 클래스 를 상속받고 있는 상황이었습니다.
단순히 생각했을때는 상속받고 있는 신청서 클래스마다 반려처리시 알람톡이 발송되게끔 코드를 작성하면 될 듯 싶습니다. 그러나 신청서의 유형은 소수가 아닌 다수였고 가장 큰 문제는 앞으로도 신청서의 유형이 증가 할 여지가 있다는 것 이었습니다.
신청서가 늘어날때마다 동일한 코드를 추가해야 되고 이는 좋지 못한 유지보수가 되어버립니다.
그래서 추상 클래스 내에 해당 기능을 정의하도록 정하였습니다. 그러나 신청서 마다 반려문구가 달라야 하는 요구사항에 대해 이를 어떻게 하면 각 신청서 유형별로 문구를 설정할 수 있을지 고민이 되었습니다.
- if ~ else 문으로 분기처리하기
- DB table 을 생성하여 신청서 유형별로 문구 select 해오기
- enum 을 사용하여 DB 를 타지 않고 application layer 에서 해결하기
이렇게 3가지의 선택지가 존재했고 전 3번을 선택하였습니다.
if~else 문으로 신청서 유형을 분기처리한다면 이 역시 각 하위 클래스마다 기능을 개발하는 것과 큰 차이가 없었으며 단 하나의 컬럼(반려문구)을 select 하기위해 DB 와 connection 을 맺는 건 비용적인 측면에서 비효율적이라고 생각했습니다.
개발과정
enum 의 맴버변수로 필요한 필드는 2개였습니다.
(신청서 유형 코드, 반려문구)
public enum NoApplType {
private String applCode;
private String noApplMessage;
}
저는 enum 생성자를 사용하여 정의할 것이므로 생성자도 추가해주고 상수 또한 정의해줍니다.
public enum NoApplType {
M003("003","신청하신 학자금 신청이 반려되었습니다.\n");
private String applCode;
private String noApplMessage;
NoApplType(String applCode, String noApplMessage) {
this.applCode = applCode;
this.noApplMessage = noApplMessage;
}
}
필자는 신청서 '코드' 값만을 가지고 반려메세지를 추출하고 싶었습니다. 이를 구현하기 위해 static
생성자와 HashMap
을 사용했는데요. static
생성자에서 모든 상수값을 (코드,반려메세지) 로 (key,value) 형식으로 구현하였습니다.
public enum NoApplType {
M003("003","신청하신 학자금 신청이 반려되었습니다.\n");
private String applCode;
private String noApplMessage;
private static final Map<String,String> codeMap = new HashMap<>();
static{
Arrays.stream(values())
.forEach(applType -> codeMap.put(applType.applCode,applType.noApplMessage));
}
public static NoApplType of(String code){
return codeMap.get(code);
}
NoApplType(String applCode, String noApplMessage) {
this.applCode = applCode;
this.noApplMessage = noApplMessage;
}
}
이렇게 말이죠. 그럼 사용자는 신청서 유형만 알고 있다면 반려처리 되었을때 신청서 코드만 넘기면 원하는 메세지를 얻게 될 수 있습니다.
enum 을 사용해서 고객이 원하는 요구사항을 개발해보았습니다.
추가
추가로 전 예외처리 구현할때 각 예외들을 enum 으로 정의하는 것을 선호합니다.
public enum ErrorType {
A001("A001","토큰이 유효하지 않습니다.", TokenIsNotValidException.class),
A002("A002","토큰이 만료되었습니다.", TokenExpiredException.class),
A003("A003","ACCESS TOKEN 이 만료되었습니다.", AccessTokenRenewException.class),
M001("M001","회원을 찾을 수 없습니다.", MemberNotFoundException.class),
M002("M002","아이디 혹은 비밀번호가 올바르지 않습니다.",MemberIdOrPasswordErrorException.class),
M003("M003","이미 등록된 아이디가 존재합니다.",ValidationMemberIdException.class),
M004("M004","이미 등록된 이메일이 존재합니다.", ValidationMemberEmailException.class),
;
private final String code;
private final String message;
private final Class< ? extends BaseException> classType;
private static final Map<Class<? extends BaseException>,ErrorType> codeMap = new HashMap<>();
static {
Arrays.stream(values())
.forEach(errorType -> codeMap.put(errorType.classType,errorType));
}
public static ErrorType of(Class<? extends BaseException> errorType){
return codeMap.get(errorType);
}
ErrorType(String code, String message, Class<? extends BaseException> classType) {
this.code = code;
this.message = message;
this.classType = classType;
}
}
이런식으로 말이죠.
그리고 모든 예외를 상속해주는 BaseException
을 선언하여 enum 값을 받게끔 합니다.
public class BaseException extends RuntimeException{
private final HttpStatus status;
private final ErrorType errorType = ErrorType.of(this.getClass());
public BaseException(HttpStatus status) {
this.status = status;
}
}
그리고 @ControllerAdvice
를 붙인 클래스에서 response
로 뱉어내는 클래스로 치환하여 클라이언트에게 응답해주면 되겠죠???
마무리
오늘은 enum 타입을 활용한 사례에 대해서 글을 작성해보았습니다.
이론적인 부분에서 이런게 있구나 라고 생각하고 실무에서는 어떨때 사용할 수 있을까? 라는 생각이 들던 차에 딱 enum 을 활용하기 좋은 고객의 요구사항이 들어왔고 무사히 잘 녹여낼 수 있었습니다.
앞으로도 학습한 내용을 바탕으로 실무에서 녹여내어 좋은 코드를 작성하는 노력을 해야겠네요!!
감사합니다
'나의 개발 메모장' 카테고리의 다른 글
wsl+docker 를 사용한 spring boot + Redis 사용하기!! (0) | 2023.06.11 |
---|---|
Http method 에 따라 동일한 URI 를 다르게 처리하는 방법 (0) | 2023.06.03 |
jvm 시스템 파라미터를 사용하여 배포환경에 따른 active 구분 (0) | 2023.05.06 |
HttpClient 를 사용해서 Rest API 웹서비스 구현해보기!!! (0) | 2023.04.18 |
@Value 어노테이션이 자꾸 null 이 나와요!!!! (0) | 2023.03.26 |