작동이 되긴 되는 제품을 출시했는데 이상하게 불안한 느낌을 받아본 적이 있다면, 소프트웨어 복잡성(Software Complexity)이 드리우고 있다는 신호일 수 있어요. 어렵지만 명쾌한 알고리즘을 푸는 재미있는 복잡성이 아니라, 고통스러운 종류의 복잡성이죠.
- 새 기능마다 예상치 못한 부작용이 생긴다
- 팀이 해결책에 대한 논의보다 단어 정의에 대해 더 많이 논쟁한다
- 간단한 변경에 몇 주의 조율이 필요하다
- “요구사항”이 문서에서는 명확해 보이는데, 구현 단계에서 모호해진다
이번 시리즈에서는 도메인 주도 설계(Domain-Driven Design, DDD)를 엔지니어링 실무가 아닌, 제품 사고에서 모호함을 줄이는 의사결정 및 협업 프레임워크로 살펴볼게요.
1. 소프트웨어 복잡성의 진짜 원인: 도메인 모호성
많은 팀이 복잡성은 기술적인 부분에서만 온다고 가정해요.
- 마이크로서비스(Microservice) vs 모놀리스(Monolith) → 아키텍처 선택이지만, 종종 불명확한 도메인 경계를 드러낼 뿐 해결하지 못함
- 어떤 데이터베이스 쓰느냐 → 최적화 결정이지만, 약한 도메인 모델을 대체할 수 없음
- 어떤 프레임워크를 쓰느냐 → 개발 생산성을 가속시켜 줄 수 있지만, 사용자의 행동을 정의하지 않음
- 클라우드 인프라를 어떻게 구축하느냐 → 확장 방법에 대한 문제이기 때문에, 명확한 도메인 이해가 선행 되어야 함
위와 같은 논쟁은 하나의 문제에 대한 현상들일 뿐이에요. 바로 팀이 도메인(Domain)에 대한 탄탄한 이해를 공유하지 못할 때죠.
여기서 도메인이란 이런 의미예요.
제품의 배경이 되는 실제 세계의 활동, 제약, 멘탈 모델(Mental Model)
즉, 사용자가 실제로 무엇을 하려 하는지, 그리고 그 환경에 어떤 “규칙”이 존재하는지예요. 도메인 이해가 약하면, 아래와 같은 상황들이 지속해서 발생하죠.
- PM과 이해관계자가 비즈니스 언어로 니즈를 설명한다
- 엔지니어가 그 비즈니스 언어를 이해하지 못한 채 기술적인 언어로 번역한다
- 그렇게 쌓인 기술 설계가 나중에 되돌리기 어려워진다
- 제품이 “우회 방법”을 축적하기 시작한다
- 기능이 그리 많지 않은데도 복잡성이 계속 증가한다
그렇게 복잡성이 쌓이다 보면 기능이 얼마 없는 제품도 새로운 기능을 붙이지 못 하는 일이 자주 발생하는 거예요.
도메인 모호성을 비유하면, 통역 없는 국제 회의와 같아요. 각 나라 대표가 자기 언어로 말하고, 상대방이 “대충 이해했겠지”라고 가정하면, 회의록은 합의처럼 보이지만 실제로는 각자 다른 것을 약속한 거예요. 소프트웨어에서도 PM, 디자이너, 엔지니어가 같은 단어를 다른 의미로 받아들이고 있으면, 코드는 “작동”하지만 의도한 것과 다른 제품이 나오죠.
2. 그저 넘겨버리는 것이 비용을 높이는 이유
비즈니스 분석 → 문서화 → 개발 구현과 같이 단계적으로 나뉘는 업무에서는 “분석”과 “설계”에 격차가 벌어지는 경향이 있어요.
- 분석 중에는 개발자가 충분히 이해하기 어려운 도메인 특화 용어로 논의가 진행돼요
- 설계 중에는 엔지니어가 빈 곳을 채우기 위해 가정을 만들어요
- 그렇게 개발물이 배포되고, 그렇게 가정에 기반한 코드 구조는 되돌리기 힘들어져요
도메인 주도 설계는 도메인 이해와 소프트웨어 설계를 연결된 상태로 유지해요. “우리가 의미하는 것”과 “우리가 만드는 것”이 일관성 있도록 만드는 거죠.
기능을 추가할 때마다 시간, 비용, 인력 기하급수적으로 올라간다면, 병목은 종종 개발 자체의 속도가 아니라 도메인 모호성이 축적된 결과에요.
3. 제품 관리의 프레임워크로서의 DDD
도메인 주도 설계를 프로덕트 관리의 관점으로 생각하면, 제품이 다루고자 하는 현실에 대해 공유된 지도를 만드는 것이에요.
1) 제품 공용 언어(Ubiquitous Language): 용어 부채를 피하는 법
제품 관리 과정에서 갈등의 원인은 용어에서 발생하는 경우가 많아요.
구독 기반 기업 학습 플랫폼을 만든다고 상상해 보세요. 회의에서 사람들이 이런 용어를 쓸 수 있어요.
- “시트(Seat)”
- “라이선스(License)”
- “멤버(Member)”
- “사용자(User)”
- “학습자(Learner)”
- “계정(Account)”
이 용어들이 혼용되면, 다음과 같은 혼란이 조용히 생겨요.
- “시트”가 유료 권한인지, 초대된 사람인지, 활성 학습자인지?
- 한 사용자가 여러 부서에 걸쳐 여러 시트를 가질 수 있는지?
- 비활성화하면 즉시 접근이 제거되는지, 결제 주기 이후인지?
도메인 주도 설계는 제품 공용 언어(Ubiquitous Language)를 정의하도록 장려해요. 프로덕트 팀이 업무 전반에 걸쳐 일관되게 사용하는 어휘죠. 조율과 이해 비용을 낮추기 위해서죠.
2) 비즈니스 규칙으로 요구사항 작성하기
기획 단계에서는 종종 두 가지 상황에 마주쳐요.
- 요구사항을 너무 모호하게 써서 재작업이 생기거나
- 요구사항을 너무 구체적으로 써서 실수로 구현 방식을 지시하거나
도메인 주도 설계는 세 번째 선택지를 제공해요. 요구사항을 UI 세부 사항이나 데이터베이스 구조가 아닌 도메인 작업과 비즈니스 규칙으로 의도를 표현하는 거예요.
이렇게 쓰는 대신:
- “시트 공유를 비활성화하는 토글을 추가한다”
다음과 표현할 수 있어요.
- “라이선스는 한 번에 한 멤버에게만 속할 수 있다”
- “멤버는 여러 워크스페이스에 속할 수 있지만, 결제는 워크스페이스 단위이다”
이렇게 하면 엔지니어에게 안정적인 기반을 주면서도, 구현 방식에는 유연성을 남기죠.
건물주가 건축가에게 요청하는 방식과 같아요. “거실에 3미터짜리 유리 슬라이딩 도어를 넣어주세요”(구현 지시)보다 “거실에서 정원이 잘 보이고 자연광이 많이 들어왔으면 좋겠어요”(의도 전달)가 더 좋은 결과를 만들어요. 건축가가 최선의 솔루션을 선택할 여지를 남기는 거죠.
3) 개념적 확장성을 정의하는 도메인 주도 설계
제품이 성장해서 확장을 해야하는 상황에서, 가장 어려운 문제는 성능이나 인프라만이 아니에요. 개념적인 문제도 커지죠.
- 같은 단어가 팀마다 다른 의미를 갖기 시작한다
- 제품의 한 부분이 더 빠르게 발전하면서 다른 곳의 가정을 깨뜨린다
- 새로운 고객 세그먼트가 기존 규칙과 충돌하는 규칙을 도입한다
강한 도메인 모델은 이런 결정을 도와줘요.
- 무엇이 함께 바뀌어야 하는지
- 무엇이 분리된 채로 있어야 하는지
- 어디에 복잡성이 존재하도록 허용할지
개념적 확장을 비유하면, 도시 계획과 같아요. 작은 마을일 때는 상점, 주거, 공장이 섞여 있어도 괜찮지만, 도시가 커지면 주거 지역, 상업 지역, 공업 지역을 명확히 나눠야 해요. 그렇지 않으면 공장 소음이 주거 지역을 망치고, 상점이 공업 지역에서 고객을 못 찾죠. 제품도 마찬가지로, 성장하면 영역 간 경계를 명확히 해야 각 부분이 독립적으로 발전할 수 있어요.
다음 편에서는 DDD의 핵심 개념인 도메인 모델이 무엇이고, 좋은 도메인 모델의 기준은 무엇인지를 구체적으로 살펴볼게요.
도메인 주도 설계 시리즈

