선택: 이음매를 기를까, 손실을 받아들일까
공용 패널은 자기 기하 정보를 앱이 대주는 키 접두사 아래 브라우저 로컬 저장소에 담아. 모드, 너비, 높이. 변환하던 앱 하나는 그 값들을 자기 설정 저장소에 두고 있었고, 게다가 내보내고 있었어. 모드 고르는 것과 크기 슬라이더 둘이 설정 팝오버에 살아 있었지.
선택지 둘. 앱이 자기 저장 백엔드를 대줄 수 있게 공용 컴포넌트에 저장 이음매를 기르거나, 공용 저장을 받아들이고 컨트롤을 지우거나.
결정은 손실을 받아들이는 거였어. 설정 컨트롤 셋이 지워졌고, 뒤에 있던 상태 필드랑 타입도 같이. 근거는 이랬어. 다른 앱들은 그 슬라이더 없이 살고, 가장자리 끌기 크기 조절이 이미 그 일을 해. 그러니까 그 컨트롤은 공용 컴포넌트가 못 푸는 문제가 아니라 다르게 푸는 문제를 풀고 있었던 거야.
이음매를 거절한 게 더 싼 답이었던 이유
저장 이음매는 무해하게 들려. 실제론 계약의 영구적 확장이야. 이제 소비자마다 저장 전략을 고르거나 기본값을 받아야 하고, 공용 컴포넌트는 유지하고 테스트할 코드 경로가 둘이 되고, 저장을 건드리는 다음 기능은 둘 다에서 돌아야 해. 그 값은 영원히, 모두가, 앱 하나가 컨트롤 셋을 지키는 대가로 치러.
그리고 이 결정이 나중에 맞아 보이게 만든 대목이 여기야. 똑같은 질문이 뒤따른 변환 셋 전부에서 나왔고, 어디서도 값이 0 이었어. 그 앱들도 기하 정보를 자기 상태에 두고 있었어. 그런데 아무도 사용자한테 내보내진 않았지. 공용 저장을 받아들이는 게 걔들한텐 안 보였어.
첫 앱을 위해 그 이음매를 붙였으면, 소비자 넷이 하나를 섬기려고 그걸 지고 다녔을 거고, 뒤의 변환 셋이 조용히 그게 불필요하다는 걸 증명했을 거야. 이미 하중을 받게 된 다음에.
저장하는 게 아니라 내보낸 걸 물어
값이 정확히 한 자리에서만 진짜였게 만든 그 구분을 뽑아둘 값이 있어. 앱 넷 다 패널 기하 정보를 저장했어. 그걸 위한 인터페이스를 지은 건 하나뿐이었고. 내부 상태는 똑같았고, 사용자한테 보이는 약속은 안 똑같았지.
변환에 값을 매길 때 질문은 앱이 뭘 쥐고 있냐가 아니라 뭘 약속했냐야. 내부 상태는 조용히 옮길 수 있어. 누가 써본 컨트롤은 못 옮기고, 진짜 값은 거기 살아. 그러니까 값 매기는 질문은 "이 앱이 뭘 저장해"가 아니라 "이 앱이 내보낸 것 중에 사용자가 사라진 걸 알아챌 수 있는 게 뭐야"야.