본문 바로가기
공부/Spring

분기문 제거

by 무심한고라니 2025. 4. 10.

좋은 글을 읽고, 기억하기 위한 용도로 남긴다.

 

---

 

지금까지 SI, SM을 하며 한 메소드 내 수백, 많게는 수천줄의 코드는 일상적이었다. 이런 코드는  수많은 분기문이 있었고 파악하기 쉽지 않았다. 자바 언어의 객체 지향을 활용한 디자인 패턴들이 적용된 깔끔한(?) 코드는 보기가 어려웠다. 그러던 중 최근에 참여했던 이커머스 프로젝트에서 팩토리 패턴[1]이 적용된 걸 봤다. 구체적인 로직은 기억이 안 나는데, 인입 채널에 따른 고객정보 생성/변경 정도였던 것 같다. 화면에서부터 개략적인 흐름을 적어보자면,

 

// Controller 메소드 내
private final AFactory aFactory;
private final AService aService;

Abstract abstract = aFactory.create(channel);
aService.createMember(abstract);

// Service 메소드 내
abstract.methodA();

 

위와 같았다. 여기서 Abstract은 추상 클래스인데 팩토리 메소드에서 인입 채널(String)에 따라 구체 클래스를 생성해주었고 이를 서비스단에 넘겨주기 위한 코드였다[2]. 즉 인입 채널에 따라 적용되는 로직을 달리 처리해주기 위해 위와 같이 패턴을 적용한 거였다. 코드를 보며 어느 정도 그 의도를 이해하기는 쉬웠지만 10개 정도 되는 구체 클래스들의 내용을 살펴보니 중복되는 코드가 많았다.

 

한편 정확히 위 사례와 같지 않아 해결책은 아니지만 if-else를 제거할 수 있는 다른 방법에 대한 글을 읽었다(이 글 남기려고 쓰는 글...). 앞의 방법이 if-else 문에 대한 애플리케이션 단위에서의 리팩토링이라면, 후자는 설계, 즉 DB 단위에서의 리팩토링이라고 할 수 있을 것 같다. 글에서는 쿠폰을 예로 들었는데, DB 설계(글에서는 편의를 위해 JSON을 사용했다)를 비교해보자.

 

 

쿠폰은 그 정책이 다양하다. 따라서 정책에 따라 다양한 쿠폰이 생성될 수 있는데 기존(A) 설계에 의하면 DB에 쿠폰에 대한 분류, 즉 일종의 판단 기준이 저장되어 있다. 로직은 이를 조회한 후 어플리케이션단에서 구현되므로 if-else문이 늘어날 수밖에 없다. 반면 B을 보면, DB에 분류가 아닌 해당하는 쿠폰에 대한 로직(type)이 저장되어 있다. 따라서 특정 쿠폰에 대한 가격을 적용하기 위해서는, 단지 해당하는 쿠폰(id) 대한 컴포넌트 리스트를 조회 후 그를 파이프 라인 모델로 적용시켜주기만 하면 된다[4].

 

지금까지는 설계, 즉 DB가 정해진대로 개발하였고 괜히 건들면 긁어부스럼이라는 생각이 많았다(물론 실력이 뒷받침되어야 하니 어느 정도는 맞다고 생각하긴 하지만). 하지만 이 글을 읽고 리팩토링시 단지 코드단에 국한하여 생각하는 것이 아니라 DB 구조도 함께 생각한다면 코드가 얼마나 깔끔해질 수 있는지 느낄 수 있었다. 앞으로 꼭 해보진 못하더라도, 설계 혹은 개발 단계에서 이러한 고민을 한 번씩 해보면 좋을 것 같다.

 

---

1. 팩토리 메소드 패턴이란

2. 엄밀하게 팩토리 메소드 패턴이라고 보긴 어렵다고 생각했다. AFactory 클래스의 create 메소드 내부는 분기문으로 구성되어 있어 인입 채널이 추가되면 코드를 변경해야 하므로 OCP에 위배되기 때문이다. 다음 글에 이에 대한 해결책[3]이 있다.

3. 다만 위 코드에서 빈이니까 당연할 거 같긴 한데... couponServiceList 필드에 모든 구체 클래스가 세팅되는지 확인해봐야 한다.

@Component
@RequiredArgsConstructor
public class ServiceFactoryV2 {
    private final List<CouponService> couponServiceList; // 초기화?
    
    /** 이하 생략 */
}

4. 실제로 쿠폰 컴포넌트가 DB 저장될 때 type 외에 order(적용순서)도 필요할지도 모르겠다. 

'공부 > Spring' 카테고리의 다른 글

예외와 응답  (0) 2025.04.12
템플릿 콜백 패턴  (0) 2021.06.21
스프링 핵심 원리 - 기본편  (0) 2021.01.18

댓글