DDD. That's not how you do it
https://www.youtube.com/watch?v=sLG5n_pXWK0&ab_channel=우아한테크
📌 DDD, 그거 그렇게 하는 거 아닌데 – 발표 정리
발표자: 박재성 (우아한형제들, 서버 개발자 / 우아한테크코스 모바일 캡틴)
🧭 발표 목적
도메인 주도 설계(DDD)를 잘못 이해하고 도입하려는 시도를 되짚어봄
그린필드/브라운필드 상황별 DDD 도입 실천 방안 제시
실제 팀 내 설계·협업 과정에서의 인사이트 공유
1️⃣ 도메인 주도 설계(DDD)란?
정의: 도메인 모델의 적용 범위를 구현으로 확장하기 위해 도메인을 탐색하고 학습하기 위한 원칙과 패턴의 모음.
출처: 에릭 에반스의 『Domain-Driven Design』 (2003)
중요 포인트: 복잡성을 다루는 철학적 접근이 핵심이지, 특정 디자인 패턴만을 의미하지 않음.
기반 철학: 객체지향(OOP), 애자일
2️⃣ 잘못된 DDD 도입 사례 (그린필드 기준)
💥 문제적 문장 3가지
“
DDD
하려면 클린 아키텍처 or 헥사고날 아키텍처를 써야 해요”“
서비스를 먼저 나눠서
마이크로서비스 아키텍처(MSA)를 시작할게요”“애그리거트, 도메인 이벤트를 도입하려면
완벽한 설계
가 필요해요”
👉 공통된 문제:
구현부터 접근
용어만 강조하며 맥락이나 목적 없는 도입
팀 내 합의와 컨텍스트 없이 구조만 흉내냄
3️⃣ 그린필드에서의 DDD
🧠 오스트랄로피테쿠스 패턴
"들으면 어려워 보이는 생소한 용어만 먼저 도입하는 행태"
예: TDD, BDD, 자일 등 무작정 도입
해결: “문제가 뭔지 → 왜 이 방법이 유효한지” 먼저 대화하고, 기술은 도구로만 활용
🔍 마이크로서비스 프리미엄
“서비스 먼저 나누고 보자” → 오히려 복잡성만 증가
해결:
초기에는 모놀리식으로 시작
단일 패키지 → 점진적 리팩토링 → 모듈 분리 → 필요 시 MSA
핵심은 아키텍처보다
올바른 **경계(바운디드 컨텍스트)**
도출즉, 도메인 분석에 대한 시간을 가져야 함
🧱 완벽한 설계는 없다
변화는 필연. 완벽한 설계를 고집하면 실행 불능
요구사항은 항상 변한다.
설계는 유연하고 자율성을 내포해야 함 → 변화 자체를 내재화하는 프로세스를 만든다. (애자일)
‘완벽’보다는 '점진적 개선' + '자기 설명 가능한 코드' 지향
4️⃣ 코드에서 시작하는 DDD
⚙️ 게터/세터는 나쁘지 않다
초기에는
getter/setter
도 괜찮음점차적으로
의미 있는 메서드
로 리팩토링 → 풍부한 도메인 모델
// Before
car.setPosition(car.getPosition() + 1);
// After
car.move();
OOP는 분명 DDD의 기반이지만, OOP는 DDD와 동일하지 않다.
💬 유비쿼터스 언어
클래스나 함수의 이름을 짓기가 너무 어렵기에 도입
모든 팀원이 같은 용어를 공유해야 함 (디자이너/기획자 포함 프로젝트의 모든 곳에서 사용)
용어 사전은 명사뿐 아니라 동사도 포함
README와 함께 리비전 관리하여 살아있는 문서로 유지(형상관리)
용어사전
Image 인수 테스트
Image 고객의 관점에서 소프트웨어가 어떻게 작동하는지를 고려한다.
5️⃣ 브라운필드에서의 DDD
브라운필드? → 출시 후 어제까지 작성한 코드가 있는 프로젝트
🎯 비즈니스 도메인을 이해해야 하는 이유
개발자의 월급은 비즈니스의 성공에서 나온다
비즈니스 도메인 = 소프트웨어로 해결하고자 하는 문제 영역
비즈니스 = 사용자의 활동과 관심사
하위 도메인으로 분해: 상품, 전시, 결제, 정산 등
🔍 도메인 분류 기준
어디서, 어떻게 돈을 벌 것인가? 우리의 비전은 무엇인가?
코어 / 서포팅 / 제너릭 (ex. 코어 = 주문, 제너릭 = 이메일 전송)
아래는 core domain chart
Image 팀 역량/자원 배분도 이에 따라 조정
📊 활용 도구
이벤트 스토밍, 도메인 스토리텔링, 컨텍스트 매핑 등 시각화 도구 활용
이제 비즈니스 문제를 어떻게 해결해야할 지 고민
6️⃣ 경계를 나누는 기준
✂️ 바운디드 컨텍스트 나누기(문제를 해결하기 위해 범위를 좁혀야 함)
바운디드 컨텍스트 = 복잡한 도메인을 명확하게 분리된 영역으로 나누는 단위
같은 용어라도 다른 의미로 쓰일 때 (ex. ‘과제’ vs ‘과제 제출물’)
외부 시스템 격리 등 개발자 의견
모두가 다르게 생각할 수 있음을 인정하고, 함께 그림 그려보기
시작은 단순하게, 점진적 분리 → “작고 중요한 것부터” (작은 문제를 하나씩 해결)
7️⃣ 외부와 단절하는 3가지 패턴
외부 시스템과 통합하다보면 용어나 로직이 오염됨. (예: userId ↔ memberId)
DTO: 외부 데이터 수용을 위한 구조체
DIP: 의존성 역전
ACL (Anti-Corruption Layer):
외부 시스템의 모델/용어가 내부로 침범하지 않도록 차단
번역 계층, Adapter 계층 등으로 구현
외부 시스템을 쉽게 교체하는 장점을 얻을 수 있음
8️⃣ 자연스러운 아키텍처 형성
DTO, DIP, ACL을 적용하다보면 자연스럽게 아키텍처가 그려짐
핵사고날/클린 아키텍처는 결과물이지 목표가 아님
핵사고날: 시스템을 중심에 두고, 포트와 어댑터를 통해 외부와 소통한다. (호환성 높임)
클린: 외부 기술은 언제든 교체될 수 있어야 한다. (구현체만 갈아끼움)
처음부터 도입하지 말고, 필요에 따라 진화시켜 나가기
구현 → 점진적 리팩토링 → 아키텍처 도출
9️⃣ 조직 내 확산 전략
변화를 유도할 사람이 필요(동맹)
호기심 유발 (ex. 화이트보드 낙서)
실제 발표자의 화이트보드
Image
Issue 발급 → 자연스러운 논의 유도 → 동료 설득
1️⃣0️⃣ 마무리 메시지
DDD는 도구가 아니라 철학
"우리에게 왜 필요한가?"라는 질문부터 시작하라
개발을 잘하는 것이 아니라, 프로젝트를 잘하는 방법이다
프로젝트에 도움이 되는 DDD 아이디어를 필터링 하여 적용
📚 추천 도서
『소프트웨어 장인』
『팀 토폴로지』
『소프트웨어 아키텍처 101』
🎯 발표에서 주목해야 할 핵심 포인트 (What to Focus On)
기술보다 문제 정의가 먼저다
“DDD 하자”는 말보다, **왜 필요한가?**를 먼저 설명해야 한다
기술 도입의 본질은 문제 해결이다
아키텍처는 진화시켜야 한다
처음부터 클린/헥사고날 아키텍처를 적용하지 말고, 구현하며 점진적으로 리팩토링하라
실무에서 처음부터 완벽한 구조를 잡는 건 환상이다
완벽한 설계는 없다
요구사항은 계속 바뀌므로 “완벽한 설계”를 추구하면 실행 자체가 안 됨
설계보다 변화 대응 능력이 중요
용어 정리는 진짜 중요하다
유비쿼터스 언어와 용어 사전은 협업 효율과 도메인 이해에 필수
코드를 명확하게 설명할 수 있어야 유지보수가 쉬워진다
바운디드 컨텍스트는 구체적 경계다
같은 단어라도 문맥이 다르면 컨텍스트를 나눠야 한다
설계 충돌을 방지하고 팀 간 협업을 원활히 만든다
느낀점
DDD에 대해 막연하게만 알고 있었는데, 이번 발표를 통해 도메인 중심의 사고방식이 왜 중요한지를 알게 되었습니다.
‘완벽한 설계는 존재하지 않는다’는 메시지와, 바운디드 컨텍스트를 함께 그려보자는 제안이 인상 깊었습니다.
‘외부와 단절하기 위한 3가지 패턴’, ‘어떻게 용어를 정리하고 점진적으로 나누는지’ 등의 구체적인 방법들이 큰 도움이 되었습니다.
Last updated