리팩토링을 시작하며: GASOMANN 프로젝트 개선 목표
백엔드 개발자로서 처음 진행했던 GASOMANN 프로젝트를 다시 들여다봤다. 솔직히 말하자면 충격적이었다. 얄팍한 지식에, "인프런에서 배운 거 얼른 써먹어야지!"라는 마음가짐, 그리고 잘하는 개발자들의 코드 느낌을 따라 해보고 싶었던 마음이 합쳐져 만들어진 결과물이 지금의 코드였다. 지금 보면 어디서부터 손을 대야 할지 모를 정도로 산만하고 정돈되지 않은 상태다.
그래도 리팩토링은 해야 한다. 하지만 전부 다 리팩토링하려다가 끝을 못 볼 가능성이 높아서, 내가 맡았던 기능들만 집중적으로 개선하려고 한다. 특히 입점 기업(가치소비), 쿠폰, 찜 기능에 초점을 맞춰 기술적이고 코드적인 개선을 진행할 예정이다.
리팩토링의 목표
GASOMANN 프로젝트에서 내가 맡았던 "입점 기업(기존 가치소비), 쿠폰, 찜" 기능을 중심으로 코드와 데이터베이스 구조를 개선하는 것이 목표다.
- 외부 API 연동이나 스트리밍 서비스 같은 신규 기술 도입은 제외한다.
- 대신, 자동 쿠폰 발급 로직 구현과 같은 반드시 필요한 비즈니스 로직 개선에 집중할 것이다.
- 현재 존재하는 기술적 부채를 해결하며, 코드와 데이터 구조의 품질을 높이는 데 초점을 맞춘다.
기존 코드에서 발견된 문제점
1. 과도한 모듈화로 인한 복잡성 증가
- 너무 세부적으로 나눠놓은 모듈화가 문제였다. 필요한 수준 이상으로 분리했더니 가독성은 떨어지고, 쿼리와 응답 속도도 느려졌다.
- 예: 입점 기업의 설명(
description
)을 List<String>
으로 처리할 수 있음에도 불구하고, 굳이 별도의 테이블로 분리.
- 결과:
- 코드를 이해하기 어렵고, 데이터베이스 설계도 복잡하게 보임.
- 쿼리와 로직이 불필요하게 늘어나 성능 저하 발생.
2. 기획 용어와 데이터 모델 간의 불일치
- 기획에서 "가치소비"라는 단어를 사용한다고 해서, 엔티티 이름도 "가치소비"로 설정했던 것이 큰 실수였다.
- 예: 입점 기업이라는 명확한 역할을 가진 엔티티를 "가치소비"로 이름 붙임.
- 결과:
- 시간이 지나고 다시 코드를 보니 "가치소비"가 무엇을 의미하는지 전혀 이해가 되지 않았다.
- 데이터 모델과 실제 비즈니스 로직 간의 괴리가 큼.
3. 인터페이스와 추상화 부족
- 인터페이스를 사용하지 않아, 구체 클래스에 직접 의존하는 코드가 많았다.
- 결과:
- 확장성 부족.
- 새로운 기능 추가 시 기존 코드를 수정해야 하는 비효율적인 구조.
4. 수동 쿠폰 발급 로직
- 기존 로직에서는 관리자가 직접 쿠폰을 발급해야 했던 문제가 있었다.
- 예: 사용자가 챌린지를 성공적으로 달성해도, 관리자가 별도로 쿠폰을 발급해야만 사용자가 혜택을 받을 수 있었음.
- 결과:
- 사용자 경험이 크게 저하되고, 관리자의 업무 부담이 증가.
- 비효율적인 프로세스로 인해 쿠폰 발급 로직의 신뢰도와 확장성이 낮음.
5. 쇼츠 관련 스트리밍 설계 부재
- 쇼츠 기능에서 동영상을 단순히 URL 저장 방식으로 처리했다.
- 예: 클라우드 스토리지나 CDN(Content Delivery Network)을 활용하지 않고 정적인 URL로만 제공.
- 결과:
리팩토링 전략
1. 리팩토링 범위
- 제외:
- 쇼츠 기능은 완전히 제외(코드 및 데이터베이스 삭제).
- 외부 API 연동, 스트리밍 서비스와 같은 신규 도입은 하지 않음.
- 포함:
- 입점 기업(기존 가치소비), 쿠폰, 찜 기능에 대한 코드와 데이터베이스 설계 개선.
- 성능 최적화, 코드 가독성 향상.
- 자동 쿠폰 발급 로직 구현.
2. 기능별 개선 방향
입점 기업 (기존 가치소비)
- 문제: "가치소비"라는 모호한 엔티티 이름, 불필요한 테이블 분리.
- 개선:
- 엔티티 이름을 "입점 기업(Value Companies)"으로 변경.
description
과 같은 과도하게 분리된 테이블 통합.
- CRUD 중심으로 로직 단순화.
쿠폰
- 문제: 쿠폰-입점 기업 관계가 명확하지 않고, 발급 로직이 비효율적.
- 개선:
- 쿠폰-입점 기업 간의 관계를 명확히 설정(1:N 관계).
- 자동 쿠폰 발급 로직 추가:
- 사용자가 챌린지를 성공적으로 완료하면, 쿠폰이 자동으로 발급되도록 로직 구현.
- 발급된 쿠폰은 사용 가능 여부, 유효 기간 등을 즉시 확인할 수 있도록 처리.
- 쿠폰 상태(active, used 등)를 관리하는 로직 강화.
찜 기능
- 문제: 단순한 기능임에도 설계와 구현이 비효율적.
- 개선:
- 사용자와 입점 기업, 쿠폰 간의 찜 상태를 통합적으로 관리하는 구조로 변경.
- 중복 찜 방지 로직 추가 및 목록 조회 최적화.
3. 데이터베이스 설계 개선
- 불필요한 테이블과 중복 칼럼 제거.
- 관계 최적화:
- 쿠폰과 입점 기업 간 관계를 1:N으로 단순화.
- 찜 기능에서 사용자와 입점 기업/쿠폰 간 관계를 통합(N:M).
- 성능 최적화:
- 자주 조회되는 데이터에 적절한 인덱스 추가.
- 복잡한 JOIN을 제거하고 간단한 쿼리로 대체.
리팩토링 단계
-
분석 단계:
- 기존 코드와 데이터베이스 구조 파악.
- 쇼츠 관련 코드와 데이터 요소 식별 및 삭제.
-
설계 단계:
- 새로운 데이터 모델과 비즈니스 로직 설계.
- 서비스 간 책임 분리.
- 자동 쿠폰 발급 로직 설계.
-
구현 단계:
- 쇼츠 관련 코드와 데이터베이스 제거.
- 설계에 맞춰 코드 리팩토링 및 데이터베이스 스키마 수정.
- 자동 쿠폰 발급 로직 구현.
-
테스트 단계:
- 기존 및 리팩토링된 기능에 대한 테스트 코드 작성.
- 데이터 일관성 검증.
배포는 리소스가 없어서 생략. 대신에 다른 프로젝트로 서버 구축 해볼 예정이다. (도커+AWS)
리팩토링의 기대 효과
- 가독성 개선: 모호한 이름과 과도한 모듈화를 제거.
- 유지보수성 향상: 코드 구조 단순화 및 인터페이스 도입으로 확장성 강화.
- 성능 최적화: 데이터베이스 설계와 쿼리 구조 개선으로 응답 속도 향상.
- 구조적 일관성: 비즈니스 로직과 데이터 모델 간의 명확한 역할 정의.
- 사용자 경험 향상:
- 챌린지 성공 시 쿠폰을 자동으로 발급받는 로직으로 사용자 편의성 증대.
- 관리자의 업무 부담 감소 및 효율적 운영 가능.
개발자의 자존심이라고 해야 할까.. CRUD만 단순하게 짠 것은 개발이라고 하고 싶지 않다. 서비스를 이해하고, 어떻게 개발을 하면 리소스 낭비를 최소한으로 줄이고 유지보수, 협업에서도 효율적으로 할 수 있을지 계속 생각을 해보면서 리팩토링을 하려고 한다.