도메인 주도 설계(DDD)의 본질과 적용

복잡성을 다루는 지혜

도메인 주도 설계(DDD: Domain-Driven Design)는 소프트웨어 개발에서 마주하는 복잡성을 효과적으로 관리하기 위한 강력한 접근 방식입니다.
그러나 많은 분이 오해하듯, DDD는 모든 프로젝트에 적용해야 하는 만능 해결책이 아닙니다. 이 글에서는 DDD 전문가들의 의견과 실제 사례를 바탕으로 DDD의 본질과 적용 시점, 그리고 그 효용성에 대해 자세히 알아보겠습니다.

1. DDD, 무엇인가요?

DDD는 끊임없는 지식 탐구 활동을 통해 적절한 도메인 모델을 선택하고, 이 모델을 기반으로 분석, 설계, 구현에 걸친 소프트웨어 개발 전 과정을 주도하며, 모델을 의사소통의 핵심 수단으로 사용하기 위해 적용할 수 있는 기법과 패턴의 집합입니다.

간단히 말해, DDD는 복잡한 비즈니스 도메인의 본질을 소프트웨어 모델에 반영하고, 이를 통해 개발자와 도메인 전문가 간의 의사소통을 원활하게 하며, 궁극적으로 변경에 유연하고 이해하기 쉬운 시스템을 구축하는 데 목적을 둡니다.
이는 단순히 코드를 잘 짜는 것을 넘어, 비즈니스 가치를 소프트웨어에 효과적으로 녹여내는 과정이라고 볼 수 있습니다.

2. DDD, 언제 필요한가요? (5%의 법칙)

많은 전문가들은 도메인 주도 설계가 매우 복잡하고 잘 정의된 비즈니스 모델에 초점을 맞춰야 하는 소프트웨어를 개발할 때 적용하기 적절한 방법이라고 강조합니다.
실제로 대부분의 소프트웨어 애플리케이션(약 95%)은 DDD를 적용하기에 적절하지 않은 범주에 속합니다.

  • 대부분의 소프트웨어는 데이터 중심적: 웹사이트, 데스크톱 애플리케이션 등 데이터를 수정하고 보고하는 대부분의 애플리케이션은 데이터 중심적이며, DDD의 복잡한 모델링이 필요하지 않습니다.
    CRUD(Create, Read, Update, Delete) 기능이 주를 이루는 시스템은 일반적으로 DDD 없이도 충분히 효율적으로 개발할 수 있습니다.

  • 단순하거나 규모만 큰 경우: 소프트웨어의 규모가 크더라도 도메인 자체가 복잡하지 않다면 DDD의 모든 기법을 적용할 필요는 없습니다.
    오히려 과도한 DDD 적용은 불필요한 복잡성과 오버헤드를 초래할 수 있습니다.
    하지만 나머지 5%에 해당하는 애플리케이션, 즉 도메인 규칙이 복잡하고 끊임없이 변경되며 상호 연결점이 많아 이해하기 어려운 경우에는 DDD가 엄청난 도움을 줄 수 있습니다.
    이런 상황에서 DDD는 "늑대를 물리치기 위한 은 총알"과 같은 역할을 하며, 난해한 비즈니스 로직을 명확하게 표현하고 관리하는 데 필수적인 도구가 됩니다.

3. DDD가 필요한 복잡성의 종류

DDD가 해결하고자 하는 복잡성은 크게 두 가지로 나눌 수 있습니다.

3.1. 도메인의 본질적인 복잡성 (Intrinsic Complexity)

이는 도메인 자체가 내포하고 있는 복잡성을 의미하며, DDD가 가장 큰 빛을 발하는 영역입니다.

  • 복잡한 도메인 규칙: 세금 계산, 금융 거래 시스템, 이커머스 시스템의 복잡한 주문 처리처럼 불변식(Invariants)과 규칙이 많고 지속적으로 변화하는 도메인은 모델을 정교하게 만들고 발전시키는 작업이 필수적입니다.
    DDD는 이러한 규칙들을 코드에 명확하게 반영하고 관리할 수 있도록 돕습니다.

  • 전사적 규모의 시스템: 대기업의 전사적 시스템처럼 규모에 따른 복잡성이 증가하는 경우, 여러 도메인 모델과 유비쿼터스 언어(Ubiquitous Language), 그리고 도메인 간의 매핑 전략을 포함하는 DDD의 전략적 패턴(Strategic Patterns)이 중요해집니다.
    이때는 핵심 도메인을 선정하고 정제하는 작업, 즉 큰 규모를 효과적으로 다루기 위한 DDD의 전략들이 필수적입니다.

3.2. 잘못된 설계로 인한 복잡성 (Accidental Complexity)

이는 도메인 자체의 복잡성보다는 잘못된 접근이나 설계로 인해 발생하는 불필요한 복잡성을 의미합니다.
DDD는 이러한 문제점을 해결하는 데도 기여합니다.

도메인과 설계, 구현의 불일치: 도메인 로직이 기술적인 코드와 혼재되어 있거나, 잘못된 설계로 중복이 많고 로직이 흩어져 있어 시스템 이해가 어렵고 변경에 취약한 경우입니다.
DDD는 도메인 로직을 핵심으로 분리하여 이러한 문제점을 해소합니다.

  • 시스템/DB 중심 사고: 도메인 전문가나 실무자가 이해하기 어려운 구조로 개발되거나, 도메인을 깊이 탐구하지 못해 좋은 인사이트를 놓치는 경우에도 DDD는 해결책을 제시할 수 있습니다. 도메인 전문가와의 긴밀한 협업을 강조하여 비즈니스 본질을 놓치지 않도록 돕습니다.
    에릭 에반스의 DDD 책에도 이러한 사례들이 여럿 등장하며, 그의 강연에서도 그 힌트를 얻을 수 있습니다.

4. DDD의 핵심 원칙: 유비쿼터스 언어와 모델

에릭 에반스의 강연에서 언급된 핵심 개념들을 통해 DDD의 본질적인 원칙들을 더 깊이 이해해 보겠습니다.

4.1. 끊임없는 지식 탐구와 대안 모색

소프트웨어 설계는 완벽주의에 빠지기 쉽습니다.
하지만 좋은 디자인을 위해서는 "필요한 것은 실행되는 소프트웨어뿐"이라는 명확한 목표를 가져야 합니다.
그리고 이 목표를 달성하기 위한 효과적인 방법이 바로 모델(Model)입니다.
중요한 것은 처음 떠오른 아이디어가 최선이 아닐 수 있다는 점입니다.

단순히 한 가지 아이디어에 집착하는 것이 아니라, 여러 대안을 탐색하고 시나리오에 따라 어떤 모델이 더 유용한지 끊임없이 고민해야 합니다.
이는 DDD가 단순히 기술적인 프레임워크가 아니라, 문제 해결을 위한 사고방식임을 보여줍니다.

4.2. 유비쿼터스 언어 (Ubiquitous Language)

유비쿼터스 언어는 도메인 주도 설계의 기본 중 하나입니다.
이는 도메인 전문가와 개발자 간의 의사소통에서 사용되는 공통의 언어를 의미합니다.
예를들어서 운송 도메인에서 '여정(Journey)'이라는 단어가 처음에는 모델에 반영되지 않았지만, 실제 도메인 전문가의 대화에서 자연스럽게 사용되는 것을 파악하고 이를 모델에 반영하는 과정을 보여줍니다.

"화물 여정은 일련의 구간으로 이루어져 있다"와 같이 도메인 전문가와 개발자가 동일한 용어를 사용하고 그 의미를 명확히 이해하는 것이 중요합니다.
이는 단순히 코드를 재정비하는 것을 넘어, 비즈니스 담당자와 소프트웨어 담당자가 동일한 방식으로 문제에 대해 이야기하고 실제 질문을 던질 수 있는 기반을 마련합니다.

  • 제한된 맥락 (Bounded Context): 유비쿼터스 언어는 전체 시스템에 걸쳐 하나일 필요는 없습니다.
    오히려 복잡한 시스템에서는 여러 개의 제한된 맥락(Bounded Context)이 존재하고, 각 맥락 내에서 고유한 유비쿼터스 언어를 가지게 됩니다. 이는 각 맥락의 독립성을 보장하고 복잡성을 관리하는 데 매우 중요한 개념입니다.

4.3. 모델의 본질과 유용성

모델은 단순한 UML 다이어그램이나 데이터베이스 스키마가 아닙니다.
세계 지도를 예시로 들어 모델의 본질을 설명합니다.

  • 추상화 시스템: 모델은 복잡한 현실(도메인)의 선택된 측면을 나타내는 추상화 시스템입니다. 모든 것을 담으려 하기보다, 특정 문제를 해결하는 데 필요한 본질적인 요소만을 담아냅니다.

  • 가정과 지식의 추출: 모델은 우리가 가진 몇 가지 가정과 지식을 추출한 결과물입니다. 이는 도메인에 대한 깊은 이해를 바탕으로 만들어집니다.

  • 목적에 따른 선택: 어떤 모델은 특정 문제 해결에 좋고, 다른 모델은 다른 문제 해결에 좋습니다. 즉, "현실을 표현하는 방법"이 아니라 "특정 문제 해결에 유용한 도구"입니다.

  • 좁은 관점과 집중: 도메인 모델은 도메인의 특정 문제를 해결하는 데 사용될 데이터의 일부 작은 선택에 대한 별도의 표현을 가져야 합니다. 즉, 모델은 특정하고 어려운 중요한 문제에 초점을 맞춰야 합니다.
    모든 것에 대해 DDD를 적용할 필요는 없습니다.
    이는 '5%의 법칙'과도 일맥상통하는 중요한 원칙입니다.

5. 깨긋한 스프링과 DDD의 지혜

비록 여러분이 지금 만들고 있는 DDD의 모든 패턴을 적용할 만큼 도메인이 복잡하지 않다고 할지라도, DDD에서 소개된 좋은 패턴과 전략, 실천법들을 적용하는 것은 많은 유익이 있습니다.

단순히 모델을 갖는다고 해서 얻는 이점은 없습니다.
이점은 해당 맥락에서 해결하려는 특정 문제 세트에 매우 잘 맞는 모델을 갖는 데서 옵니다.
프로젝트에서는 이러한 DDD의 지혜를 바탕으로 유연하고 이해하기 쉬운 설계를 목표로 접근하고 있습니다.
이는 당장 복잡하지 않더라도, 미래의 확장성과 유지보수성을 고려하는 현명한 방식입니다.

DDD는 단순히 기술적인 패턴의 집합을 넘어, 도메인을 깊이 이해하고 끊임없이 모델을 개선하려는 "지식 탐구 활동"입니다.
여러분의 프로젝트가 복잡한 도메인의 본질적인 문제에 직면했을 때, DDD는 분명 훌륭한 나침반이 되어줄 것입니다.

참조

What is DDD - Eric Evans - DDD Europe 2019

profile
에러가 나도 괜찮아 — 그건 내가 배우고 있다는 증거야.

0개의 댓글