ASP.NET 쪽의 현장별 정산 기능을 CodeIgniter 쪽으로 옮기게 되어 옛 코드만 읽으면 될 줄 알았다. 같은 것을 만들어 돌려 보니 새 시스템에 옛 시스템이 전제하던 것이 없었다.
Table of contents
Open Table of contents
배경 — 옛 코드만 읽고 만든 것
옮긴 코드가 Session["user"] 를 찾는데 새 시스템은 JWT 기반이라 그런 것이 없었다. 코드는 그대로인데 그 코드가 기대는 바탕이 사라진 상태였다.
옮기려면 옛 코드만이 아니라 새 시스템이 무엇을 전제하는지도 알아야 했다. 한쪽만 읽고 옮기면 그 코드가 무엇에 기대는지를 못 본다.
원인 — 양쪽 방식이 다섯 가지 달랐다
인증과 설정 읽기와 데이터 접근과 오류 처리와 로그 다섯이 서로 달랐다. 세션과 Authorization: Bearer 가 다르고 Web.config 와 .env 가 다르고 SqlDataReader 와 쿼리 빌더가 다르고 예외 페이지와 JSON 오류 응답이 다르고 이벤트 로그와 log_message 가 달랐다.
표로 적어 놓고 하나씩 대응을 정했다. 옮기는 것은 복사가 아니라 옛것을 새것의 방식으로 다시 쓰는 일이었다.
조치 — 그대로 둘 것과 바꿀 것
업무 규칙과 계산식과 조건 판단은 그대로 두는 쪽을 골랐다. 이유는 그것까지 바꾸면 옮기는 것이 아니라 새로 만드는 것이 돼서다. 대신 옛 계산식에 든 어색한 구조를 이번에 정리하지 못하는 것을 감수했다.
인증과 설정과 데이터 접근과 오류와 로그만 새 방식으로 바꿨다. 무엇을 지킬지를 먼저 정하니 어디까지가 이 작업인지가 분명해졌다.
검증 — 옛 결과와의 대조
옮긴 것이 옛것과 같은 결과를 내는지 보려고 입력과 옛 결과를 오백 건 뽑아 두고 대조했다. 열여덟 건이 달랐고 열어 보니 셋으로 갈렸다.
옛것이 틀린 것과 새것이 틀린 것과 반올림 방식이 달라 둘 다 맞는 것이었다. 공식 문서대로 .NET 의 Math.Round 는 기본이 짝수로 반올림이라 12.5 가 12 가 되고 PHP 의 round 는 기본이 0에서 먼 쪽이라 13 이 된다. 옛것이 틀린 경우가 있었으므로 그대로 옮겼으면 문제까지 함께 옮겼을 것이다.
막힌 지점 — 안 옮길 것과 원본의 방향
옛 시스템의 기능 중 사용 기록이 없는 것과 새 시스템에 이미 있는 것과 업무가 없어진 것은 안 옮기기로 하고 이유를 적어 확인받았다. 마지막 것은 물어봐서 알았고 코드만 보면 아직 쓰는 것으로 보였다.
둘이 같이 도는 기간에는 어느 쪽이 원본인지를 시점으로 갈랐다. 옮기는 순서는 가장 단순한 것부터로 잡았는데 첫 기능에서 방식 차이를 전부 만나고 나면 나머지는 그 길로 지나가기 때문이다.
정리
- 옮기는 것은 옛것을 새것의 방식으로 다시 쓰는 일이다
- 한쪽만 읽으면 그 코드가 무엇에 기대는지를 못 본다
- 양쪽의 방식 차이를 표로 적고 대응을 정한다
- 업무 규칙은 그대로 두고 주변만 바꾼다
- 옛 결과를 뽑아 두고 같은 결과가 나오는지 대조한다
- 옛것이 틀린 경우가 있으므로 그대로 옮기면 문제도 옮긴다
- 안 옮길 것을 정하고 이유를 적어 확인받는다
- 둘이 같이 도는 동안 어느 쪽이 원본인지 시점으로 가른다