메트로놈 Simple Metronome TIL 5
저장 묶음의 경계는 데이터가 아니라 사용자의 기대가 정한다
연습 설정을 이름 붙여 저장하는 프리셋을 넣었다. 무엇까지 담을지가 첫 결정이었다.
앱이 가진 설정은 여러 가지다. 템포, 박자표, 소리 종류 같은 연주 설정이 있고 테마 색, 화면 깜빡임 같은 전역 설정도 있다. 기술적으로는 전부 담을 수 있었다.
연주 설정만 담기로 했다. 사용자가 프리셋을 부르는 상황은 “아까 그 리듬으로 돌아가자”이지 “아까 그 화면으로 돌아가자”가 아니다. 리듬 하나를 불렀는데 앱 색이 바뀌면 고장으로 느껴진다.
저장 기능을 만들 때 담을 항목은 “저장 가능한가”가 아니라 “불러올 때 같이 바뀌어도 사용자가 놀라지 않는가”로 고른다. 이 기준이 있으면 항목이 늘어날 때마다 다시 판단할 수 있다.
개수가 변하는 목록은 칸을 늘리지 말고 한 덩이로 넣는다
프리셋은 몇 개가 될지 모른다. 처음 떠오른 방법은 저장소에 프리셋 1, 프리셋 2처럼 칸을 늘려 가는 것이었는데, 이러면 중간을 지우거나 순서를 바꿀 때마다 번호를 다시 매겨야 한다.
대신 목록 전체를 문자열 하나로 바꿔서 한 칸에 저장했다. 이렇게 구조를 문자열로 펴는 것을 직렬화라고 하고, 여기서는 JSON 형식을 썼다. 이름과 값이 짝지어진 구조를 글자로 적어 두는 방식이다. 읽을 때는 반대로 되돌린다.
칸이 하나뿐이니 추가·삭제·순서 변경이 전부 목록을 다루는 일이 되고, 저장은 매번 통째로 덮어쓰면 끝난다. 항목 수가 수십 개 수준이면 이 단순함이 성능보다 이득이다.
읽는 쪽에는 한 가지를 더 뒀다. 저장된 글자가 깨져 있으면 빈 목록으로 시작하게 했다. 사용자 기기에서 무슨 일이 있었는지는 알 수 없고, 그때 앱이 죽는 것보다 프리셋이 비는 편이 낫다.
새로 저장과 덮어쓰기를 사용자에게 고르게 하지 않는다
저장할 때 이름이 이미 있으면 그 자리를 갱신하고, 없으면 새로 추가한다. 사용자는 이름만 정하면 되고 “새로 저장”인지 “덮어쓰기”인지 고르지 않는다.
대신 이미 있는 이름이면 덮어쓸지 한 번 묻는다. 프리셋 삭제도 마찬가지로 묻는다. 되돌리기 기능이 없는 앱에서는 이 확인 한 번이 되돌리기를 대신한다. 확인을 넣을 자리는 “실수하면 복구할 방법이 있는가”로 정하면 된다.
기능을 지우는 일은 화면을 지우는 게 아니라 흔적을 찾는 일이다
프리셋이 생기니 예전에 만든 “마지막 템포 기억하기” 스위치가 할 일이 없어졌다. 프리셋이 그 역할을 더 잘한다.
지우는 게 만드는 것보다 쉬울 줄 알았는데 아니었다. 화면에서 스위치를 빼는 것은 시작일 뿐이고, 그 기능이 남긴 자리가 여기저기 흩어져 있었다. 값을 들고 있던 자리, 저장소 이름표, 화면이 뜰 때 연결하던 부분, 값이 바뀔 때 부르던 부분, 그 기능만 쓰던 함수까지 있었다.
그래서 순서를 이렇게 잡았다. 지우기 전에 관련된 이름들로 전부 검색해 목록을 먼저 만들고, 목록대로 지운 다음, 같은 검색을 다시 돌려 하나도 안 남았는지 확인했다.
여기서 알게 된 게 하나 더 있다. 코드에서 안 쓰는 함수를 남겨 두면 대개 경고라도 뜨는데, 그림이나 스타일 같은 자원은 안 써도 아무 말이 없다. 도구가 안 잡아 주는 종류의 쓰레기가 따로 있어서, 기능을 걷어낼 때는 그 기능이 데려온 자원 목록도 직접 세어 봐야 한다.
겉을 바꿔도 이름을 유지하면 연결이 안 끊긴다
저장 버튼을 화면 전체 폭을 쓰는 큰 버튼에서 헤더 오른쪽의 작은 아이콘으로 바꿨다. 생김새도 부품 종류도 달라졌는데 코드는 한 줄도 안 고쳤다. 그 부품에 붙여 둔 이름표를 그대로 뒀기 때문이다.
디자인을 바꾸는 작업이 비싸질 때와 싸질 때가 여기서 갈린다. 이름표를 유지하면 껍데기 교체는 거의 공짜고, 이름표까지 바꾸면 그 이름을 쓰던 자리를 전부 따라다녀야 한다. 겉모양을 자주 손볼 것 같은 자리일수록 이름을 먼저 안정시켜 두는 게 좋다.
효과 없음을 확인하고 되돌리는 것도 결론이다
첫 박이 작게 들리는 문제를 다시 잡아 보려고, 소리를 더 빠른 경로로 내보내는 설정을 켜 봤다. 체감 차이가 없었고 그대로 되돌렸다.
되돌렸지만 버린 시간은 아니다. 소리 데이터 자체는 크기가 같다는 것을 이미 확인했고, 여기서 재생 경로를 바꿔도 안 변한다는 것까지 확인했으니, 원인이 앱 바깥에 있을 가능성이 그만큼 올라갔다. 남은 후보가 줄어든 것이 결과다.
안 되는 시도를 기록해 두면 다음에 같은 길을 다시 파지 않는다. 기록하지 않으면 몇 달 뒤에 똑같은 설정을 또 켜 보게 된다.
요약
- 저장 묶음에 넣을 항목은 “저장 가능한가”가 아니라 “불러올 때 같이 바뀌어도 안 놀라는가”로 고른다.
- 개수가 변하는 목록은 저장 칸을 늘리지 말고 통째로 한 덩이로 만들어 한 칸에 넣는다. 추가·삭제·순서 변경이 전부 목록 다루는 일로 바뀐다.
- 되돌리기가 없는 앱에서는 확인 한 번이 되돌리기를 대신한다. 확인을 넣을 자리는 복구 가능성으로 정한다.
- 지우는 일은 만드는 일보다 쉽지 않다. 지우기 전에 검색으로 목록을 만들고, 지운 뒤 같은 검색으로 0건을 확인한다.
- 자원은 안 써도 아무 경고가 없다. 도구가 안 잡아 주는 쓰레기는 직접 세어야 한다.
- 겉모양을 바꿔도 이름표를 유지하면 연결이 안 끊긴다. 자주 손볼 자리일수록 이름을 먼저 안정시킨다.
- 안 되는 것을 확인한 것도 결과다. 남은 후보가 줄어든 만큼 다음 탐색이 짧아진다.