피드로 돌아가기
원문 읽기
LINE Engineering
Backend코드 품질 개선 기법 29편: 고르디우스 변수
LY Corporation이 로컬-원격 데이터 동기화 코드의 복잡한 의존성을 중간 데이터 구조 도입으로 단순화
AI 요약
Context
로컬과 원격 저장소 간 FooData를 동기화하는 FooSynchronizer 구현 시, 데이터의 의존성이 복잡하게 얽혀 코드 흐름을 따라가기 어려웠다. remoteEntryIds와 localEntryIds를 여러 번 사용하면서 동일한 데이터가 중복 참조되었고, 업데이트 로직에서는 필요 없는 런타임 에러 처리가 추가되었으며, 삭제 로직과 추가·업데이트 로직 간 일관성이 맞지 않았다.
Technical Solution
- 로컬과 원격의 모든 ID 집합 allEntryIds를 생성: remoteEntryMap.keys + localEntryMap.keys로 통합
- 각 ID에 대해 (원격 데이터, 로컬 데이터) 쌍 생성: allEntryIds.asSequence().map { id → remoteEntryMap[id] to localEntryMap[id] }
- partitionByNullity 확장 함수 구현: Sequence<Pair<S?, T?>>를 Triple<List, List<Pair<S, T>>, List>로 분할하여 추가·업데이트·삭제 항목 세 쌍 생성
- partitionByNullity 내부 로직: (null, 값) → 추가, (값, 값) → 업데이트, (값, null) → 삭제로 when 조건 분기하여 각 항목을 해당 List에 추가
- 각 항목군에 대해 순차적으로 처리: createdEntries, updatedEntries, deletedEntries의 forEach를 독립적으로 실행
Key Takeaway
데이터의 의존성이 복잡할 때는 이상적인 중간 데이터 구조(createdEntries, updatedEntries, deletedEntries)를 역으로 설계해 도입하면, 복잡한 조건문과 중복 참조를 제거하고 함수 흐름을 명확하게 부각시킬 수 있다.
실천 포인트
추가·업데이트·삭제 같이 여러 변환 규칙을 적용해야 하는 동기화 로직에서 null 여부 조합을 기반으로 partitionByNullity 같은 범용 분할 함수를 구현하면, 각 케이스별 데이터를 미리 정리하여 처리 로직을 단순하고 일관성 있게 작성할 수 있다.