DDD 는 TDD와 함께간다
도메인 주도 개발을 하다보니 테스트도 항상 같이 하고 있었다. 그래서 알아보기로
도메인 주도 개발을 아시나요
도메인 주도 개발(DDD, Domain-Driven Design)
- DDD는 소프트웨어의 핵심을 “도메인(문제 영역)”에 집중하여 설계하고 개발하는 방법론이다.
- 즉, 비즈니스 로직을 제대로 모델링하고 유지보수하기 쉽게 만드는 것이 목표이다.
쉽게 말해서 일단 프로그램이 어떤 일을 해야 하는지 제대로 알아야 잘 만들수 있다! 이다.
그럼 도메인은 뭐야?
DDD가 도메인에 집중하여 설계하고 개발하는 방식이이라면, 가장 중요한 건 도메인에 대해서 제대로 알고 가야하는 것이다.
도메인에 대한 이야기는 < 도메인(Domain)이 뭐냐고? >를 참고하자.
그래도 요약해서 말하자면, 도메인은 어떤프로그램이 해결하려는 문제나 주제를 말한다.
- 즉, “이 프로그램이 무슨 일을 하려고 하는거야?” 이다.
게임을 예로 들어보자
게임 종류 | 해결하려는 문제(도메인) |
---|---|
포켓몬 게임 | 몬스터를 모으고, 배틀을 해서 챔피언이 된다. |
마인크래프트 | 자원을 모아서 건물을 짓고 생존한다. |
레이싱 게임 | 자동차를 운전해서 가장 빨리 결승선을 통과한다. |
게임을 만들려면, 먼저 “이 게임에서 가장 중요한 게 뭘까?” 를 정해야 한다.
- 포켓몬 게임이라면? “포켓몬을 모으고 키우고 배틀에서 승리하는 것”
- 레이싱 게임이라면? “자동차를 종착점까지 빠르게 달리는 것”
이렇게 프로그램이 해결하려는 문제(도메인) 를 먼저 정하는 게 중요하다.
결국, 우리가 만들어가 나가는 프로젝트와 그에 따른 문제의 이해가 중요한 것이다.
도출해 낸 문제들을 바탕으로 개발 을 이어나간다. 이것이 도메인주도설계(DDD)의 핵심이다.
도메인 주도 개발(DDD)은 어떻게 진행될까?
“무조건 먼저 코딩하지 말고, 도메인을 먼저 이해하자!” 라면, 아래와 같은 방식으로 진행 된다.
예시: 피자 가게의 주문 시스템 만들기
그럼 우리가 먼저 해야 할 일은?
- 가게에서 실제로 어떻게 주문이 처리되는지 알아본다.
- 손님이 피자를 주문하면?
- 직원이 피자를 만들고?
- 배달부가 배달
- 가장 중요한 개념(도메인)을 정리
- “주문(Order)”
- “피자(Pizza)”
- “배달(Delivery)”
- 이 개념들을 서로 어떻게 연결할지 생각
- 손님이 피자를 주문하면?
- 직원이 주문을 확인하고 피자를 만들고?
- 배달부가 손님에게 배달해야겠죠?
도메인 주도 개발이 왜 중요할까?
- 비즈니스(실제 현실)와 코드가 잘 맞는다.
- 예를 들어 피자 가게 사장님(기획자?)이 시스템을 보고도 이해할 수 있어야 한다.
- “이건 피자 주문 시스템이지, 포켓몬 게임이 아니잖아요..?”라는 말이 나오면 안된다.
- ✅ 팀원들끼리 쉽게 이야기할 수 있다!
- 개발자, 디자이너, 기획자 모두 같은 용어(유비쿼터스 언어)를 사용하면 헷갈리지 않는다.
- 예를 들어, “주문이 생성되었다” VS “고객이 피자를 선택했다” 같은 말을 다르게 하면 혼란이 생겨 버리기 시작하고 소통에 오류가 생기기 시작한다.
- 모두가 같은 언어로 소통하기 때문에 전체 프로젝트 개발의 진행 속도가 확연히 빨라진다.(빠른 피드백 효과 ✅)
- 유지보수가 쉬워진다.
- 시간이 지나면서 추가적인 요구사항이 생기면, 이미 도메인에 대한 확립을 했기 때문에 쉽게 수정할 수 있다.
이제 도메인이 확립되었으니 코드를 구성하고 테스트를 한다.. 응? 그런데 계속 테스트 코드르 짜야하네?
” 그럼 테스트코드 부터 짜고 거기에 맞는 코드를 구현하면 안정성도 확보되고 코드 피드백도 빠르게 받을 수 있지 않을까?”
그렇다. 그것이 Test-Driven Development(TDD) 의 핵심이다.
테스트 주도 개발(TDD)이 뭐냐면
위의 링크가 있으나 간단히 설명하자면, 테스트 주도 개발(Test Driven Development) 은 매우 짧은 개발 사이클을 반복하는 소프트웨어 개발 프로세스이다. 개발자는 먼저 요구사항을 검증하는 자동화된 테스트 케이스를 작성한다. 그 이후에는 테스트 케이스를 통과하기 위한 최소한의 코드를 생성하고, 작성한 코드를 리팩토링하는 과정을 반복
TDD의 과정
- 일단 간단하고, 해보기 쉬운 것을 먼저 시도
- 실패하는 테스트를 통과하기 위해서는 최소한의 코드를 작성
- 테스트를 점점 구체화할수록 프로덕션 코드는 점점 범용적으로 된다. (커버 가능한 케이스가 점점 많아집니다.)
- 실패하는 테스트가 있을 때만 프로덕션 코드를 작성
- 실패를 나타내는 데 충분한 정도의 테스트만 작성
위와 같은 부분들을 의식하면서, 테스트 주도 개발 사이클을 반복하다 보면, 작성한 코드가 가지는 불안정성을 개선하여 생산성을 높일 수 있다. 또한, 테스트 가능하며 결합이 느슨한 시스템을 점진적으로 만들어 나갈 수 있다. 하지만, 테스트 주도 개발이 오히려 비효율적인 경우도 존재하기 때문에 다른 모든 기술과 마찬가지로 비판적으로 사고하는 것도 중요하다고 생각한다.
도메인 주도 개발(DDD)과 테스트 주도 개발(TDD)은 항상 함께인가?
- 도메인 주도 개발(DDD)을 한다고 해서 항상 테스트 코드(TDD)를 적용해야 하는 것은 아니다.
- 하지만 우리는 개발을 할 때 테스트코드를 꼭 작성하는 것이 중요하다고 배운다. 왜? 비즈니스 로직이 올바르게 동작하는지 확인하려면 테스트 코드는 필수다.
그렇다면 도메인을 정확히 인지하고 테스트 코드를 짜고 실제 코드를 구현한다면?
- 도메인의 핵심 개념을 명확히 정의하면서도 기능이 정상적으로 동작하는지 지속적으로 검증할 수 있다. -> 빠른 피드백 덕분에 보다 안정적이고 예측 가능한 코드를 만들 수 있다.
아 이보다 더 조화로운 방법이 있을까?
그래서 DDD와 TDD는 매우 궁합이 좋은 개발 방법론이라고 부르나 보다.
DDD와 TDD의 차이
DDD와 TDD는 서로 다른 개념이다.
구분 | DDD (도메인 주도 개발) | TDD (테스트 주도 개발) |
---|---|---|
목적 | 현실 세계의 문제(도메인)를 정확히 모델링 | 코드가 올바르게 동작하는지 테스트 |
중심 | 비즈니스 로직(도메인) | 테스트 코드(코딩) |
진행 방식 | 도메인을 먼저 이해하고 설계 → 구현 | 테스트를 먼저 작성 → 테스트 통과하는 코드 작성 |
연관성 | 도메인을 잘 이해하면 테스트도 쉬워짐 | 테스트를 하면서 도메인 로직을 점검 가능 |
- 즉, DDD는 “무엇을 만들 것인가?”,
- TDD는 “제대로 만들고 있는가?” 를 검증하는 역할을 한다.
가장 좋은 방법은 함께 하는 것
우리가 진행하는 서비스를 빠르고 정확하게 하기 위해서는 두 가지의 개발론이 함께 하는 것이 좋다고 생각된다.
도메인이 정확히 도출되기까지 회의에 많은 시간이 걸릴 수도 있지만, 그렇게 하지 않았을 때의 비용이 더 클 수 있다.
도메인 도출 -> 테스트 코드 -> 코드 구현 -> 리펙토링
도메인이 확립되고 그에 맞는 코드를 테스트 하면서 구현하다보면 실시간으로 코드의 질을 높일 수 있다.
분명, 초반에는 시간이 걸릴 수 있지만, 루틴이 익숙해지면 코드 작성 속도가 빨라질 것이다.
그렇다면 회사에서 원하는 제품 서비스를 보다 빠르게 배포까지 가능하다.
코드를 짜면서 클린코드적인 부분도 생각하면 좋은데, 테스트 코드를 작성하면서 하나씩 기능 혹은 모델링이 늘어나면 변경 되는 부분을 하나하나 계속해서 바꿔줘야 하는 불상사가 발생한다.
(산탕총 수술(Shotgun Surgery) 이라고 명시하는데 이 부분은 다음 포스팅에서 다뤄보겠다.)
개발의 세계는 멀고도 험하지만, 역시 흥미롭달까.🤩
참고 자료