[리팩토링] 무분별한 팝업창 코드 공통 함수로 리팩토링
in Development on Problem Solving, 리팩토링
#목차
문제
- 프로젝트 이관 작업 중 유효성 및 팝업창의 코드를 무분별히게 생성하여 중복코드 발생.
- 사용자가 조회, 등록, 등 작업을 하려는 행위들을 했을 때 사용자에게 안내 팝업창과 저장했으면 저장, 취소했으면 취소하는 행동의 팝업창을 띄워주고 있는데, 그 코드들을 계속 새로 작성하여 중복코드가 상당히 발견되는 상황을 발견하였다.
문제의 재현 코드
// file: "문제의 javascript파일.js"
function processDone(jqXHR, textStatus, errorThrown) {
// ...
if (jqXHR.status == 500) {
Swal.fire({
title: '알림',
text: '내부 시스템 에러',
icon: 'error',
confirmButtonText: '확인',
}).then(function (result) {
if (result.value) {
alertify.error('내부 시스템 에러');
}
});
} else if (jqXHR.status == 404) {
Swal.fire({
title: '알림',
text: '경로가 잘못 되었습니다.',
icon: 'error',
confirmButtonText: '확인',
}).then(function (result) {
if (result.value) {
alertify.error('경로가 잘못 되었습니다.');
}
});
} else if (jqXHR.status == 408) {
Swal.fire({
title: '알림',
text: '잠시 후 다시 시도해 주세요.',
icon: 'error',
confirmButtonText: '확인',
}).then(function (result) {
if (result.value) {
alertify.error('잠시 후 다시 시도해 주세요.');
}
});
} else if (jqXHR.status == 401) {
errorAlert('접근 권한이 없습니다.');
} else if (jqXHR.status == 403) {
Swal.fire({
title: '알림',
text: 'ID 또는 비밀번호를 확인해주세요.',
icon: 'error',
confirmButtonText: '확인',
}).then(function (result) {
if (result.value) {
alertify.error('ID 또는 비밀번호를 확인해주세요.');
}
});
}
if (jqXHR.getResponseHeader("SESSION_EXPIRED") != null ) {
Swal.fire({
title: '알림',
text: '세션이 만료되어 로그인 페이지로 이동합니다.',
icon: 'error',
confirmButtonText: '확인',
}).then(function (result) {
if (result.value) {
location.href = "/login";
}
});
}
}
- 위 코드를 보게 되면
api
호출 후 응답 결과에 따른 안내 팝업창을 나타내는 코드이다. - 위 조건문 안에
Bootstrap
의 팝업 기능인Swal.fire()
부분의 코드들이 중복적으로 계속 발생한다는 것을 알 수 있다. - 위 코드처럼 사용하게 되면 만약, 기능들이 추가되거나 사용자에게 팝업 형태의 알림을 보여줘야 할 때 계속 비슷한 코드를 사용해야 한다는 문제가 발생한다.
- 그것을 방지하고 함수로 정의하여 호출하는 형태로 바꾸어 아래 코드처럼 리팩토링하였다.
리팩토링 재현 코드
// file: "sg.ajax.js"
function processFail(jqXHR, textStatus, errorThrown) {
// ...
if (jqXHR.stat표us == 500) {
notification('내부 시스템 에러', 'error', null);
} else if (jqXHR.status == 404) {
notification('경로가 잘못 되었습니다.', 'error', null);
} else if (jqXHR.status == 408) {
notification('잠시 후 다시 시도해 주세요.', 'error', null);
} else if (jqXHR.status == 401) {
notification('접근 권한이 없습니다.', 'error', null);
} else if (jqXHR.status == 403) {
notification('ID 또는 비밀번호를 확인해주세요.', 'error', null);
}
// ...
if (jqXHR.getResponseHeader("SESSION_EXPIRED") != null ) {
notification('세션이 만료되어 로그인 페이지로 이동합니다.', 'error', () => { location.href = "/login"; });
}
// ...
}
- 위 코드처럼 리팩토링하여 약
71%
의 코드 사용량을 줄였다. - 물론 코드가 예제 파일 파일 한 곳에 결과를 반영한 것으로 실제와 다를 순 있다.
- 하지만, 확실한 건 코드의 사용량이 예제 코드를 통해서만 보아도 많이 줄일 수 있다는 것을 볼 수 있다.
리팩토링 공통 함수 재현 코드
// file: "리팩토링.js"
/**
* Notification (success/error/warning/question/info alert)
*
* @param text 팝업 문구
* @param type 팝업 종류 : success, error, warning, info
* @param method 실행 메서드
* @returns Swal.fire
*/
function notification(text, type, method) {
// When text and type are not used
if (text === null || type === null) {
return Swal.fire({
title: '알림',
text: '시스템 오류가 발생했습니다. 관리자에게 문의해주세요.',
icon: 'warning',
confirmButtonText: '확인',
});
}
// Common Alert
return Swal.fire({
title: '알림', // 알림
text: text,
icon: type,
showCancelButton: type === 'question' ? true : false,
confirmButtonText: '확인',
cancelButtonText: '취소',
}).then((result) => {
if (result.isConfirmed) {
method();
} else if (result.isDismissed) {
notification('취소 하였습니다.', 'warning', null);
}
});
}
- 위 파라미터
text
의 경우 공통 팝업 창의 안내 문구를 넣어주는 파라미터이다. type
은 팝업창의 아이콘 타입으로error
,warning
,success
을 통해 공통 팝업창의 아이콘을 설정할 수 있게 된다.method
의 경우 공통 팝업 창의 실행 후 추가적인 작업이 이 필요할 때 함수를 넣어주는 파라미터이다.- 따라서, 위 공통 함수 코드로 리팩토링하여 사용자에게 필요한 팝업창을 제공하고 싶을 때 호출하여 사용하면 된다.
- 매번 사용자에게 팝업 알림 창을 보여줘야 하는 코드를 만들어서 보여주는 것보다 그곳에서 해당 공통 함수를 호출하여 제공하면 코드 사용량이 줄어들어 유지 보수에도 편하게 된다.
결론
- 리팩토링을 통해 코드가 훨씬 간결해졌다.
- 또한 유지 보수가 편리해졌다는 것을 알 수 있다.
- 이렇게 리팩토링을 진행하면서 리팩토링의 재미를 느끼게 되었다. 위 코드 또한 좀 더 리팩토링해볼 수 있지 않을까? 란 생각을 잠시나마 해본다.