반응형
Notice
Link
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | |||||
3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 |
31 |
Tags
- I'm Sorry
- 알고리즘
- 보안
- 데이터과학
- 웹개발
- 데이터분석
- 소프트웨어
- 버전관리
- 인공지능
- Yes
- 머신러닝
- 자료구조
- 컴퓨터비전
- 자바스크립트
- springboot
- 파이썬
- 네트워크보안
- 컴퓨터과학
- 프로그래밍
- 데이터베이스
- 사이버보안
- 프로그래밍언어
- 디자인패턴
- 클라우드컴퓨팅
- 데이터구조
- 빅데이터
- 컴퓨터공학
- 네트워크
- 소프트웨어공학
- 딥러닝
Archives
- Today
- Total
스택큐힙리스트
친구 추천 서비스, 왜 무너졌을까? SRP 위반 리팩터링 실전 해부 본문
반응형
“친구 추천 코드를 뜯어보니 추천·랭킹·알림·로깅까지 한 클래스에 다 들어 있었다.”
SNS 서비스에서 친구 추천은 트래픽을 좌우하는 핵심 기능입니다. 그런데 출시 1년 만에 버그가 폭발하고 배포가 두려워진 팀이 있었습니다. 원인은 단 하나, SRP(단일 책임 원칙) 위반이었습니다. SRP란 “클래스가 변경돼야 할 이유는 하나여야 한다”는 원칙이죠 이번 글에서는 실제로 벌어졌던 ‘친구 추천 서비스’의 SRP 위반 패턴을 해부하고, 단계별 분리 전략을 살펴봅니다.
1. 실패의 전조 – 거대 FriendRecommendationService
초기 구현은 다음과 같았습니다.
- 데이터 수집: 사용자 그래프·활동 로그·팔로잉 기록 한꺼번에 조회
- 후보 생성 + 랭킹: 협업 필터링 점수 계산 후 랭킹 적용
- 알림 전송: 푸시·이메일 발송
- 모니터링/로깅: 추천 결과·클릭률을 로그로 저장
네 가지 책임이 한 클래스에 얽히면서 “새 랭킹 알고리즘” 한 줄을 바꾸려 할 때마다 알림 로직과 로그 스키마까지 동시에 깨지는 참사가 발생했습니다. 대용량 트래픽을 받는 추천 시스템은 “후보 생성 단계·랭킹 단계로 나눠라”는 것이 정석인데 이를 무시한 결과였습니다.
2. 코드 냄새 체크리스트로 본 SRP 위반
리팩터링 전에 SRP 코드 냄새를 스캔했습니다
- if/else 지옥: ‘ABTestType’에 따라 알고리즘이 분기
- UnsupportedOperationException: 채널이 없는 테스트 환경 때문에 예외 던짐
- 300줄 메서드: recommend() 내부에서 그래프 DB 쿼리 → 점수 계산 → 푸시 발송까지 처리
모두 “변경 이유가 여럿”이라는 SRP 위반 신호였습니다.
3. 5단계 분리 가이드
- 역할 라벨링
클래스·메서드 옆에 포스트잇을 붙여 “데이터 추출”, “랭킹”, “알림”처럼 역할을 명시했습니다. 두 개 이상이면 분리 대상. - 인터페이스 추출
- CandidateGenerator
- ScoreCalculator
- NotificationSender
- RecommendationLogger
각각을 작은 클래스로 분리하고 전략 패턴으로 교체 가능하게 설계.
- 의존성 주입(DI)
스프링 Bean으로 구현체를 주입해 고수준 서비스가 구체 클래스에 직접 의존하지 않도록 역전(DIP) 시켰습니다. - 계약 테스트 추가
상위 타입에 대한 Mock 테스트를 먼저 작성해 하위 구현을 안전하게 교체. - 점진적 배포 + Feature Toggle
새 구조를 기능 토글로 감싸 트래픽 10% → 100%로 단계적 전환.
4. 분리 후 얻은 효과
- 릴리스 주기 2주 → 3일: 알림 채널 추가도 코드 수정 없이 구현체만 추가
- 장애율 –40%: 랭킹 알고리즘 실험이 다른 모듈에 영향 없음
- 테스트 커버리지 +25%: Mock 주입이 쉬워져 빠른 단위 테스트 가능
무엇보다 “추천 품질 팀”과 “알림 팀”이 서로의 코드에 간섭하지 않게 되면서 조직 생산성이 눈에 띄게 상승했습니다.
5. 실무 팁
- 메트릭으로 감시: 클래스 크기(Lines of Code)·메서드 복잡도를 SonarQube 알람으로 설정.
- 로그 스키마 버전 관리: 로거를 분리하면 스키마 변경을 독립적으로 배포 가능.
- A/B 테스트 자동화: 후보 생성기·점수 계산기를 전략 패턴으로 바꿔 실험 스위치를 손쉽게 켜기.
반응형
'개발' 카테고리의 다른 글
Gradle 캐시 최적화로 빌드 시간 단축하기 (0) | 2025.07.13 |
---|---|
자바 스프링 개발 시작하기 - 7일차 코드 품질 높이는 Git Flow·PR·CI (1) | 2025.07.13 |
SRP 리팩터링 체크리스트: 코드 냄새 없애는 7단계 (0) | 2025.07.13 |
DIP: 추상화로 의존을 뒤집자! (3) | 2025.07.13 |
인터페이스는 “딱 쓰는 만큼만!” ― ISP(인터페이스 분리 원칙) 완벽 가이드 (0) | 2025.07.13 |
Comments