도메인 주도 설계
Domain-driven Design
방법
업무에서 쓰는 말과 그 말이 갈라지는 경계를 기준으로 시스템을 나누고 코드를 짜는 설계 방법입니다.
등장 배경
업무를 아는 사람과 코드를 쓰는 사람이 같은 것을 다른 이름으로 부르는 일이 오래된 골칫거리였습니다. 영업은 계약이라고 하는데 코드에는 주문이라고 적혀 있고, 회계는 청구서라고 부르는데 화면에는 명세서라고 떠 있습니다. 회의는 매번 그게 코드의 어느 것인지 확인하는 번역으로 시작했습니다.
말이 어긋나면 고치는 자리도 어긋납니다. 계약이 끝나면 알림을 멈춰 달라는 요청이 들어왔을 때, 그 계약이 코드에서는 세 군데에 나뉘어 있고 이름이 각각 달랐습니다. 두 군데만 고치고 배포한 뒤 해지한 고객에게 결제 안내가 계속 나갔습니다. 잘못은 코드 실력이 아니라 같은 것을 같은 이름으로 부르지 않은 데 있었습니다.
시스템을 나누는 기준에도 같은 문제가 있었습니다. 화면 단위나 데이터베이스 표 모양으로 덩어리를 가르면 업무 규칙 하나가 여러 덩어리에 흩어집니다. 도메인 주도 설계는 기준을 바꾸자고 제안합니다. 업무에서 쓰는 말을 먼저 맞추고 그 말이 달라지는 자리를 찾아 그 선을 따라 가르자는 것입니다. 여기서 도메인은 그 제품이 다루는 업무 영역을 가리킵니다.
사용 절차
업무를 아는 사람과 만드는 사람이 한자리에서 말을 맞추는 것부터 시작합니다. 절차는 여섯 단계로 이어집니다.
- 같은 것을 뭐라 부를지 하나로 정합니다. 페이지덱에서는 문서와 페이지가 섞여 쓰이고 있었는데, 사람이 여는 한 장을 문서로 정하고 그 안을 나눈 단위는 블록으로 부르기로 했습니다. 이렇게 합의한 어휘를 팀 전체가 씁니다.
- 정한 말을 코드에 그대로 적습니다. 회의에서 문서라고 부르기로 했으면 화면도 함수도 테이블도 문서라는 이름을 씁니다. 코드에만 통하는 별명을 따로 두면 1번이 무의미해집니다.
- 같은 단어가 다른 뜻으로 쓰이는 자리를 찾아 선을 긋습니다. 편집 쪽에서 문서는 블록이 쌓인 덩어리지만 요금 쪽에서 문서는 사용량 한 건입니다. 뜻이 갈리는 이 자리가 경계이고, 경계 안에서만 그 어휘가 통합니다.
- 경계마다 핵심 규칙을 코드로 옮깁니다. 이 부분이 비즈니스 로직입니다. 무료 플랜은 문서를 30개까지 만들 수 있고 팀 플랜은 제한이 없다는 규칙이 화면이나 데이터베이스가 아니라 이 자리에 모여 있어야 합니다.
- 경계끼리 주고받는 방식을 정합니다. 요금 쪽이 편집 쪽 데이터를 직접 읽게 둘지, 정해진 창구로만 묻게 할지를 고릅니다. 이 선택이 두 덩어리의 결합도를 정합니다.
- 말이 바뀌면 코드도 함께 바꿉니다. 업무에서 쓰는 어휘가 바뀌었는데 코드가 옛 이름을 쥐고 있으면 1번에서 맞춘 것이 다시 어긋납니다.
앞의 세 단계가 어디를 자를지 정하고 뒤의 세 단계가 그 안을 채웁니다. 코드 구조부터 잡으면 경계를 다시 그을 때 그 구조가 전부 어긋납니다.
적합한 상황과 한계
업무 규칙이 복잡하고 자주 바뀌는 제품에 맞습니다. 요금 계산에 플랜·할인·환불·세금이 얽혀 있고 그 규칙이 분기마다 손질된다면, 말을 맞추고 경계를 긋는 데 쓴 시간이 나중에 고치는 시간으로 돌아옵니다. 여러 팀이 한 시스템을 나눠 맡을 때도 경계가 곧 담당 구역이 됩니다.
반대로 맞지 않는 자리도 분명합니다.
- 규칙이랄 것이 없는 제품 — 값을 넣고 읽고 고치고 지우는 일이 전부인 내부 관리 도구라면 경계를 그을 거리가 없습니다. 이름만 거창해지고 파일 수만 늘어납니다.
- 업무 전문가를 만날 수 없는 경우 — 재료를 업무를 아는 사람과의 대화에서 얻는 방법입니다. 물어볼 사람이 없으면 개발자끼리 상상한 용어집이 남고, 그건 예전과 같은 문제입니다.
- 무엇을 만들지 아직 모르는 단계 — 초기 제품처럼 한 달 뒤에 방향이 통째로 바뀔 수 있는 상황에서는 지금 그은 경계가 오래가지 않습니다.
한계도 있습니다. 회의와 학습에 드는 시간이 먼저 나가고 효과는 나중에 나타나서 일정이 급한 팀에서 가장 먼저 잘려 나갑니다. 경계를 처음부터 정확히 긋는 일도 어렵습니다. 쓰다 보면 선을 잘못 그었다는 것이 드러나고 그때 옮기는 비용이 적지 않아서, 모듈러 모놀리스처럼 한 덩어리로 배포하되 안만 갈라 두는 구조에서 먼저 시험해 보는 편이 안전합니다. 경계를 마이크로서비스로 바로 쪼개 놓으면 선을 옮길 때 배포 단위까지 함께 옮겨야 합니다.
실무 용례
"이건 결제 컨텍스트 밖이에요. 문서 쪽에서 가져다 쓰면 안 됩니다."
경계를 넘어 남의 데이터를 직접 읽지 말고 정해진 창구를 쓰라는 말입니다.
"용어집부터 맞추고 시작하죠. 지금 회의록에 같은 걸 세 이름으로 부르고 있어요."
코드를 짜기 전에 어휘를 하나로 정하자는 제안입니다.
"폴더만 DDD 모양이지 규칙은 전부 화면 쪽에 있어요."
구조는 흉내 냈지만 규칙이 제자리에 없다는 지적입니다.
페이지덱에서는 요금 기능을 다시 만들 때 이 방법을 처음 꺼냈습니다. 지현이 업무 쪽 어휘를 정리해 오고 태오가 코드에 남아 있는 이름을 나란히 적어 대조했는데, 같은 대상을 부르는 이름이 다섯 개였습니다. 첫 두 주는 코드를 거의 쓰지 않고 이름을 맞추는 데 썼습니다.
그 뒤로 요금 규칙이 바뀔 때 손대는 자리가 한 곳으로 줄었습니다. 대신 편집 쪽과 요금 쪽이 문서라는 말을 다르게 쓰게 되어, 두 팀이 함께 보는 자리에는 어느 쪽 뜻인지를 적어 두기로 했습니다.
흔한 오해
폴더 구조와 패턴 이름을 따라 쓰는 것으로 아는 경우가 가장 많습니다. 책과 예제가 엔티티·리포지토리 같은 구현 패턴을 자세히 다루다 보니 눈에 먼저 들어오는 것이 그쪽입니다. 하지만 이 방법의 재료는 업무를 아는 사람과 나눈 대화이고, 패턴은 그렇게 얻은 모델을 코드로 옮기는 수단입니다. 순서를 뒤집으면 폴더는 교과서 모양인데 규칙은 여전히 화면 쪽에 흩어져 있는 상태가 됩니다.
마이크로서비스를 하려면 거쳐야 하는 단계로 읽는 것도 흔합니다. 서비스를 어디서 자를지 정할 때 이 방법이 자주 인용되기 때문입니다. 그러나 경계는 업무의 말이 갈라지는 자리이고 배포 단위는 운영상의 선택이라 둘이 늘 같지 않습니다. 모놀리스 한 덩어리 안에서도 경계를 그어 쓸 수 있고, 오히려 그쪽이 선을 다시 옮기기 쉽습니다. 이 둘을 붙여 두면 경계를 정리하려던 팀이 서비스 분리부터 시작하게 되고, 잘못 그은 선 위에 배포 구조까지 얹혀 되돌리기가 훨씬 어려워집니다.
같이 보면 좋은 페이지
- 소프트웨어 아키텍처
이 방법이 답해 주는 나누기 문제 전체를 봅니다
- 디자인 패턴
같은 설계 지식 갈래에서 코드 단위의 정형화된 해법을 다룹니다
연관 용어
마지막 업데이트 2026-09-16