기능을 접는 일은 결정 하나가 아니다
잘 만든 기능을 지우며 배웠습니다. 코드와 데이터는 따로 판단하고, 기능은 품질이 아니라 원리로 재판하고, 반쯤 도는 것은 남기지 않는다는 것을.
기능을 만드는 일에는 절차가 있습니다. 문제를 정하고, 범위를 자르고, 만들고, 내보냅니다. 기능을 접는 일에는 보통 절차가 없습니다. 쓰는 사람이 적어 보이면 메뉴에서 빼고, 코드는 언젠가 정리하겠다고 남겨 둡니다. 저도 그렇게 해 왔습니다.
최근 두 제품에서 잘 만들어 둔 것들을 지웠습니다. 관계를 읽는 서비스 somesignal에서는 기능 셋을, 야구 팬 서비스 DUGOUT 9에서는 배포처 하나를 지웠습니다. 지우면서 알게 된 것은, «접는다»는 한 단어 안에 성격이 다른 결정이 세 개 들어 있다는 것이었습니다. 무엇을 남길지, 무엇으로 판단할지, 어디까지 지울지입니다.
코드는 과감하게, 데이터는 보수적으로
somesignal에는 두 사람이 만날 장소를 추천하는 기능이 있었습니다. 백엔드 2,780줄, 직접 고른 장소 126곳, 342줄짜리 수집 절차 문서, 운영 스크립트 여섯 개, 전용 테스트 열 개. 품질이 낮지 않았습니다. 다만 받는 쪽이 거의 없었고, 피드백은 한 건도 오지 않았습니다. 장소를 더 모으는 일은 이미 멈춰 두었습니다. 그런데 멈춘 것은 부채가 자라는 일이었지, 부채를 갚은 것은 아니었습니다. 장소 데이터는 낡아 가고, 코드는 여전히 읽히고 테스트되고 있었습니다.
그래서 지웠습니다. 코드와 시드 데이터, 스크립트, 테스트까지 약 12,000줄입니다. 다만 데이터베이스의 테이블과 컬럼은 남겼습니다. 지운 것은 우리가 더는 쓰지 않기로 한 코드이고, 이미 저장된 남의 기록은 다른 문제이기 때문입니다. 지난 약속에 장소가 붙어 있던 기록은 화면이 깨지지 않도록 그대로 읽습니다.
둘을 한 덩어리로 다루면 어느 쪽이든 잘못하게 됩니다. 코드를 데이터처럼 아끼면 부채를 계속 지고, 데이터를 코드처럼 지우면 되돌릴 수 없게 됩니다. 지운 코드는 버전 기록에서 언제든 돌아오지만, 지운 기록은 돌아오지 않습니다. 비용 구조가 정반대이니 판단도 따로 해야 했습니다.
잘 만든 기능을 원리로 재판한다
같은 시기에 somesignal은 원리를 하나 새로 정했습니다. 가입하지 않아도 결과부터 본다. 그런데 관계 지도 안에는 상대의 별을 두드리는 기능과 질문 카드가 있었습니다. 둘 다 상대가 회원이고 앱을 열어야 성립합니다. «가입하지 않아도 된다»와 «상대를 불러라»는 같은 화면에서 동시에 참일 수 없었습니다.
두 기능에 결함이 있었던 것은 아닙니다. 새로 정한 원리와 어긋났을 뿐입니다. 이럴 때 기능을 하나씩 심사하면 대개 살아남습니다. «이거 잘 만들었나»라는 질문에는 잘 만든 기능일수록 쉽게 «그렇다»고 답하게 되기 때문입니다. 물어야 할 질문은 «이것이 우리 원리 안에서 성립하나»였고, 그 질문 앞에서 둘은 성립하지 않았습니다. 그렇게 원리가 둘인 제품이 되는 것을 막는 일이 기능 하나를 지키는 일보다 중요했습니다.
지우는 범위도 그 원리를 따랐습니다. 새로 만드는 길은 닫았지만, 이미 남은 기록은 타임라인에서 계속 보입니다. 실제로 만나는 약속은 남겼습니다. 원리 안에서 성립하고, 현실에서 결과를 만들기 때문입니다. 지운 기능에 기대던 것들도 함께 손봤습니다. 받을 일이 없어진 알림의 설정 스위치를 화면에 남겨 두면, 아무것도 조절하지 않는 스위치가 사람을 속이게 됩니다.
반쯤 도는 것은 남기지 않는다
DUGOUT 9에는 예전에 두 번째 배포처가 있었습니다. 그쪽에는 데이터베이스와 스케줄러가 연결되어 있지 않아서, 그 주소로 들어온 사람의 기록은 하나도 남지 않았습니다. 그런데 링크와 빌드 설정은 살아 있었습니다.
선택지는 두 가지였습니다. «기록 기능만 빠진 버전»으로 살려 두거나, 빌드 타깃째 지우거나. 살려 두는 쪽이 덜 과감해 보였습니다. 하지만 반쯤 도는 두 번째 주소가 있으면 공유 링크와 검색 결과, 앱 껍데기가 어느 쪽을 가리키는지 매번 헷갈리게 되고, 그 혼란은 오류 메시지가 아니라 사용자의 기록이 조용히 사라지는 모습으로 나타납니다. 그래서 지우고, 배포처를 하나로 못 박았습니다.
«일단 살려 둔다»의 비용은 유지비라고 생각하기 쉽습니다. 실제 비용은 모호함이었습니다. 반쪽짜리 두 번째 경로는 선택지가 아니라 실수가 일어날 표면이었습니다.
접는 일에도 설계가 있다
세 결정을 나란히 놓고 보면 공통점이 하나 있습니다. 셋 다 «지울까 말까»가 아니라 «무엇을 기준으로 어디까지»를 정하는 일이었습니다. 코드와 데이터를 가르는 선, 기능을 재는 원리, 반쪽을 허용하지 않는 경계입니다. 그 선을 긋지 않고 지우면 지나치게 지우거나 모자라게 지우게 됩니다.
기능을 만들 때 쏟는 주의의 일부를 접을 때도 쓰려고 합니다. 접는 일은 실패를 정리하는 뒷일이 아니라, 제품이 무엇인지를 다시 정하는 일이기 때문입니다.