[하루 한 시간] 모델링 시리즈: 조건 트리 공부해보기..

이종호·2025년 10월 5일

하루 한 시간

목록 보기
8/13

출처: https://kciter.so/posts/modeling-series-conditional-tree/

복잡한 비즈니스 로직, 문 지옥에서 벗어나는 5가지 놀라운 사실

서론: 늘어나는 조건문, 언제까지 복사-붙여넣기 하실건가요?

"고객이 장바구니에 상품 X를 담고 있을 때 첫 구매자거나, 최근 한단 내 구매 금액이 10만원 이상이면서 등급이 VIP라면 쿠폰을 노출해주세요."

만약 이런 비즈니스 요구사항을 받는다면 어떻게 구현하시겠습니까?
처음에는 간단한 if문으로 해결할 수 있겠지만,
제품이 성숙하고 기능이 고도화될수록 조건은 꼬리에 꼬리르 물고 늘어납니다.
if-else블록이 끊업이 중첩되고, 비슷한 로직이 여기저기 복사-붙여넣기 되면서 코드는 복잡성의 늪에 빠지게 된다.

제품이 성숙해지면서 마주하게 되는 현실적인 요구사항들은 다음과 같습니다.

  • 다양한 상황에 대한 조건을 평가해야 하는 경우
  • 관리자가 개발자에 의존하지 않고 직접 조건을 편집하고 싶어 하는 경우
  • 런타임 중에 동적으로 조건이 변경되어야 하는 경우
  • 평가에 사용되는 데이터가 실시간으로 변하는 경우.

단순히 if문으로 사용하는 것만으로는 이러한 요구사항을 모두 충족하기 어려움
오늘 소개한 조건 트리는 이 모든 문제를 해결할 수 있는 강력하고 우아한 패턴임

1. 모든 복잡함의 시작: 문장으 '블록'처럼 분해하기

"모든 추상화는 필요한 것을 찾아 필요한 것을 뽑아내는 것 부터 시작한다."

복잡해 보이는 요구사항도 차분히 들여다보면 단순한 요소들의 조합으로 이루어져있음
예를 들어, "나이가 18세 이상이면서 첫 구매거나 VIP인 경우"라는 문장을 어떻게 분해할 수 있을까?
이 문장은 조건식과 조건 연산자라는 2가지 단순한 요소로 나눌 수 있음

먼저 조건식만 뽑아내면 다음과 같습니다.

  • 나이가 18세 이상 (age >= 18)
  • 첫 구매 (purchaseCount == 0)
  • VIP (level == VIP)

다음 조건 연산자를 뽑아내 보겠습니다.
문장은 "이면서(AND)"와 "거나(OR)"라는 연산자로 각 조건식을 연결하고 있습니다.
이 2 요소를 결합하면 복잡했던 자연어 문장은
age >= 18 AND (purchaseCount == 0 OR level == VIP)라는 명확하고 추상화된 식으로 변환됩니다.
이처럼 복잡하 자연어 요구사항을 단순한 논리 블록으로 분해하는 것, 이것이 바로 조건 트리의 첫 걸음이자 놀라운 발상의 전환임

2. 레고 블록을 조립하듯: 단순한 '트리'구조의 무한한 확장성

앞서 분해한 논리 블로들을 어떻게 조합해야 연산자 우선순위 같은 문제를 해결할 수 있을까?
정답은 트리 구조에 있다.
각 논리 블록을 노드로 만들어 계층적으로 연결하면 아무리 복잡한 조건이라도 명확하게 표현할 수 있음

조건 트리는 단 2가지 유형의 노드로 구성됨

  • Leaf 노드: 더 이상 분해할 수 없는 단일 조건 (예: "나이 >= 18")
  • Composite 노드: AND, OR, NOT과 같으 논리 연산자로, 다른 노드를 연결하는 역할을 함

우리는 예시에서 (purchaseCount == 0 OR level == VIP)는 하나의 Composite OR노드가 됨.
이 노드는 age >= 18이라는 리프 노드와 함꼐 Composite AND 노드의 자식이 됨.
이처럼 트리의 계층 구조 자체가 괄호의 역할을 자연스럽게 수행하여, 복잡한 파싱 로직 업이도 연산자 우선순위 문제를 우하하게 해결ㅏㅎㅁ.

이러한 구조는 바로 'Composite 디자인 패턴'을 활용한 것.
이 단순한 2종류의 노드만 있으면 아무리 복잡한 조건이라도 일관되고 체계적으로 표현 가능.

3. 개발자의 자유 로직과 데이터의 완벽한 분리

조건 트리를 만들었다면, 이제 트리가 '참'인지 '거짓'인지 평가해야함
ConditionEvaluator느 ㄴ트리의 각 노드를 순회하며 최종 겨과를 계산하는 역할을 함
여기서 가장 핵심적이 ㄴ개념은 AttributeResolver임
ConditionEvaluator가 사용자의 나이가 18세 이상인가? 라는 리프 노드를 평가할 때, 사용자의 실제 나이가 몇 살인지 알아야 함
AttributeResolver는 바로 이 시점에 필요한 실제 값을 외부에서 동적으로주입해주는 정보제공자 입니다.

이러한 분리 구조 덕분에, 조건 평가 로직은 데이터가 어디서 오는지(DB, 실시간 세션, 외부 API 등) 전혀 신경 쓸 필요가 없게 됨.
이것이 바로 개발자에게 진정한 자유를 선사하는 지점.
가장 복잡한 비즈니스 로직을 테스트하기 위해 더이사 데이터베이스를 실행하거나 전체 애플리케이션 환경을 구성할 필요가 없습니다.
그저 테스트 데이터를 제공하는 가짜 AttributeResolver를 만들어 중입하기만 하면 됨

4. 모두를 위한 유연함: 마케터와 기획자도 코딩 없이 규칙을 만든다.

조건 트리의 진정한 힘은 비개발자에게 강력한 도구가 될 수 있다는 점에서 나옴

마케터는 관리자 화면에서 레고 블록을 조립하듯 놀리 블로과 조건 블로을 마우스로 끌어다 놓ㅎ으며 새로운 규칙을 만듬
VIP고객을 위하 ㄴ깜짜 할인 판매를 기획했다면, 마케팅팀이 몇분 만에 직접 조건을 설정하고 캠페인을 시작할 수 있음

이러한 유연성은 특정 조건을 만족하는 사용자에게만 쿠폰을 발급하는 마케팅 자동화, 개인화된 상품 ㅍ추천, 사용자 역할에 따른 기능 접근 권한 관리 등 비즈니스의 민첩성이요구되는 다양한 영역에서 빛을 발함.

5. 그것은 '룰 엔진'이 아닙니다. 가장 흔한 오해 바로잡기.

많은 개발자가 조건 트리에 대해 듣고 "그거 그냥 단순한 룰 엔진 아니야?"라고 생각할 수 있습니다.
둘다 조건을 평가한다는 점에서는 비슷해보이지만, 실제로는 구조, 역할, 활용 범위가 전혀 다릅니다.

핵심적인 차이는 범위와 목적에 있습니다.
조건 트리는 '지금 이 조건이 참인가, 거짓인가' 라는 단 하난의 복잡한 질문에 답하기 위해설계된 정밀 도구임.
그 결과는 단순한 Boolean값입니다.
반면, 룰 엔진은 전체 규칙 집합을 평가하여 '어떤 행동을 취해야 하는가'를 결정하는 복잡한 의사결정 시스템입니다.
단순히 참/거짓을 반환하는 것을 넘어, 수 많은 'IF/THEN' 규칙 중 어떤 것을 만족하는지에 따라 특정 결과를 실행하는 것이 목적입니다.
이 때문에 룰 엔진은 여러 규칙 간의 우선순위 충돌 해결 전략 같은 복잡한 개념이 필요하지만, 조건 트리는 그렇지 않음

정리하자면 조건트리는 단일 조건식으로 판단해야할 때, 혹은 복잡한 조건을 관리자 화면에서 간단히 조정하고 싶을 때 주로 사용됩니다.
반면 룰 엔진은 수백 개 이상의 규칙을 동시에 평가하거나 규칙 기반의 복잡한 비즈니스 로직을 구현해야할 때 유용합니다.

결로: 잘 만든 모델 하나가 선사하는 놀라운 변화

오늘 살펴본 '조건 트리'는 단순히 복잡한 if 문을 대체하는 기술이 아님, 이것은 비즈니스 요구사항을 추상화하고, 구조적으로 설계하며, 각 요소의 책임을 명확히 분리하는 사고방식의 중요성을 보여줌

이러한 잘 추상화된 접근법은 단순히 코드를 정리하는것을 넘어, 시스템이 할 수 있는 일의 근본적인 기능성을 바꿈

profile
코딩은 해봐야 아는 것

0개의 댓글