웹 서비스에 있던 현황판 기능을 모바일 앱에 읽기 전용으로 이식했습니다. 국가별 참여 현황을 도넛 차트로 보여주는 화면입니다.
로직과 수치는 서버 응답을 그대로 검증해서 바이트 단위로 일치시켰습니다. 차이 0이었습니다.
그런데 화면에서 눈에 띈 문제는 숫자가 아니라 색이었습니다.
당신은 원본 구현을 베낍니까, 더 간단해 보이는 방식으로 새로 짭니까?
해시는 충돌합니다
도넛 차트의 국가별 색상을 국가 코드 문자열의 해시값으로 뽑고 있었습니다. "코드마다 고유한 색을 자동으로 배정한다" — 아이디어는 그럴듯합니다.
라이브 데이터로 렌더링했더니 영국과 독일이 같은 초록색이었습니다.
팔레트가 6색뿐입니다. 해시값이 충돌하면 그대로 같은 색이 나옵니다. 범례를 봐도 어느 색이 어느 나라인지 구분이 안 됩니다.
6색 팔레트 + 해시 인덱싱 → 국가 코드에 따라 충돌 가능
6색 팔레트 + 순위 인덱싱 → 같은 화면 안에서는 충돌 불가원본 웹 서비스는 이 문제를 겪지 않았습니다. 국가를 해시가 아니라 순위 순서로 팔레트에 인덱싱하고 있었기 때문입니다. 몇 번째로 큰 나라냐에 따라 색이 정해지므로, 같은 화면 안에서는 절대 충돌할 수 없습니다.
원본이 이미 피해뒀던 문제를, 더 간단해 보이는 방식으로 새로 짜면서 다시 만든 셈입니다.
같은 성격의 함정 둘이 더 있었습니다
- 차트 라이브러리의 "적당한 개수만 눈금을 그려라" 옵션이 범주형 축에서는 무시됐습니다. 14개 국가 라벨이 전부 겹쳐서 그려졌습니다. 라이브러리 기본값을 믿지 않고 그릴 눈금을 직접 골라 넘겨야 했습니다.
- 웹 문구를 그대로 옮겼다가, 같은 화면 안 바로 옆 타일과 같은 말이 됐습니다. "오늘 새로 생긴 항목 수"를 뜻하는 라벨이 "오늘 새로 들어온 사용자 수"를 뜻하는 옆 타일과 구분되지 않았습니다.
세 번째가 특히 재미있습니다. 웹에서는 옆에 그 타일이 없었기 때문에 이 모호함이 드러나지 않았을 뿐입니다. 문구 자체는 한 글자도 안 바뀌었는데, 옮겨진 맥락에서 틀린 문구가 됐습니다.
여기서 선택이 갈립니다
이식한 화면을 어떻게 검증할 것인가. 안드로이드 릴리스 빌드는 로그인 관문 때문에 실제 화면을 직접 볼 수 없었습니다.
당신이라면 릴리스 빌드 검증을 포기하겠습니까, 간접 증거로 대신하겠습니까?
간접 증거로 했습니다. 난독화된 빌드 안에 관련 문자열·클래스가 살아있는지, 크래시가 0건인지를 확인했습니다.
다만 그게 무엇을 증명하는지는 정확히 적어둬야 합니다. 디버그 빌드에서는 라이트/다크 양쪽을 눈으로 봤지만, 릴리스 빌드는 "안 깨졌다"만 확인한 것이지 "제대로 보인다"까지 확인한 게 아닙니다.
자가진단
- 색·순서를 해시로 배정하고 있습니까? 팔레트 크기보다 항목이 많으면 충돌은 시간 문제입니다.
- 원본 구현이 왜 그렇게 돼 있는지 확인하고 베꼈습니까, 더 간단해 보여서 새로 짰습니까?
- 옮겨온 문구가 새 이웃과 같은 말을 하고 있지 않습니까?
솔직한 부분
서버 응답과 앱 화면의 수치는 스칼라 값 6개, 국가별 필드 12개, 시계열 4종, 상위 목록 전 필드를 대조해서 차이 0을 확인했습니다. 숫자는 처음부터 맞았습니다.
문제는 그 숫자를 색으로 바꾸는 마지막 단계에만 있었습니다. 정확도를 검증하는 데 쓴 시간의 대부분이, 실제로 틀린 자리를 비껴가 있었던 셈입니다.
당신이 최근 이식한 화면에서, 원본과 다르게 짠 부분을 하나 골라 왜 다르게 짰는지 적어보세요.