MSA 도메인 구조 기반 리팩터링 및 시스템 통합
1. 프로젝트 개요 및 목표
해당 과제는 기존에 자사가 지향하는 개발 방향 및 표준 솔루션 구조와 어긋난 형태로 개발된 특정 파트의 메뉴들을 전면 리팩터링하는 작업이었습니다. 주요 목표는 레거시 코드를 분석하여 우리 회사의 솔루션 구조 및 MSA 환경에 최적화된 구조로 재설계하고, 전체 시스템에 안정적으로 통합하는 것이었습니다.
2. 기존 아키텍처의 문제점 및 기술적 부채
리팩터링에 앞서 코드 리뷰를 진행한 결과, 다음과 같은 심각한 기술적 부채가 확인되었습니다.
- 도메인 로직의 파편화 및 혼재: 핵심 비즈니스 로직들이 Controller(프레젠테이션 계층)와 Repository(데이터 접근 계층) 등에 무분별하게 섞여 있어 일관된 설계 원칙을 찾기 어려웠습니다.
- 하드코딩된 데이터 및 계산식: 주요 상숫값이나 복잡한 계산 로직들이 코드 내부에 직접 박혀(Hard-coded) 있어, 정책 변경 시 관련된 모든 파일을 찾아 수정해야 하는 위험이 컸습니다.
- 높은 결합도와 부작용(Side-Effect): 모듈 간의 강한 결합으로 인해 한 부분의 수정이 전혀 예상치 못한 다른 기능에 버그를 유발할 가능성이 높았습니다.
3. 문제 해결 전략: 사내 표준과 이론적 기반의 교차 검증
막막한 상황을 해결하기 위해 무작정 코드를 수정하기보다 확실한 기준점을 세우는 전략을 취했습니다.
- 사내 PPT 자료를 통한 아키텍처 가이드라인 확립: 사내에서 제공되는 아키텍처 교육용 PPT 자료를 깊이 있게 분석하여, 우리 회사가 지향하는 계층 간 통신 규약과 도메인 분리 기준을 명확히 파악했습니다.
- 전문 서적을 통한 DDD(도메인 주도 설계) 학습: 실무적 기준을 뒷받침할 이론적 근거를 확보하기 위해 『도메인 주도 설계로 시작하는 마이크로서비스 개발』이라는 서적을 참고했습니다. 이를 통해 도메인 이벤트, 애그리거트(Aggregate) 등의 개념을 실제 코드에 어떻게 매핑할지 구체적인 전략을 수립했습니다.
- 하드코딩 로직의 공통화(Centralization): 곳곳에 흩어진 계산식과 데이터를 식별하고, 이를 일관되게 관리할 수 있도록 '공통 코드(Common Code)'로 추출하여 통합 관리하는 기준을 마련했습니다.
4. 리팩터링 수행 및 아키텍처 개선 과정
4.1 Enum과 전략 패턴(Strategy Pattern) 도입
하드코딩된 if-else 지옥을 해결하기 위해 Enum과 전략 패턴을 결합하여 로직을 객체화했습니다.
| 구분 | 내용 |
|---|---|
| Before | 하드코딩된 조건문 중심의 할인 계산 로직 |
| After | Enum과 전략 패턴을 적용하여 정책별 계산 책임을 분리한 구조 |
[Before] 하드코딩된 레거시 코드 예시
public double calculateDiscount(String grade, double price) {
if ("VIP".equals(grade)) {
return price * 0.2; // VIP 20% 할인 직접 입력
} else if ("GOLD".equals(grade)) {
return price * 0.1;
}
return 0;
}
[After] Enum 전략 패턴 적용
public enum DiscountPolicy {
VIP(price -> price * 0.2),
GOLD(price -> price * 0.1),
BASIC(price -> 0.0);
private final Function<Double, Double> expression;
DiscountPolicy(Function<Double, Double> expression) {
this.expression = expression;
}
public double calculate(double price) {
return expression.apply(price);
}
}
4.2 트러블슈팅: Enum과 DB 의존성 분리
리팩터링 과정 중 Enum 내부에서 DB 조회가 필요한 상황이 발생했습니다. Enum은 Spring Bean이 아니므로 Repository를 주입받을 수 없는 제약이 있었습니다. 이를 해결하기 위해 DB 조회는 Service 계층에서 수행하고, Enum에는 순수한 데이터(Data)만 파라미터로 넘겨 계산 결과만 반환하도록 책임을 분리했습니다. 결과적으로 Enum은 독립적으로 단위 테스트가 가능한 순수한 도메인 객체로 남을 수 있었습니다.
5. 최종 성과
결과적으로 회사 표준에 어긋났던 파트의 메뉴들을 성공적으로 리팩터링하고 통합했습니다. 단순히 코드를 고치는 것을 넘어, 사내 아키텍처 가이드와 외부 설계론을 융합하여 실무에 적용하는 아키텍처 설계 역량을 강화할 수 있었으며, 이는 향후 유지보수 비용을 획기적으로 줄이는 밑거름이 되었습니다.
obBears