반응형

 

도메인 주도 설계(DDD, Domain Driven Design) 소개

 

도메인이 무엇인가요?

 

도메인의 사전적 의미는 '소프트웨어로 해결해야 할 문제의 영역'입니다. 일반적으로 요구사항이라고 불리는 것들이며 이것을 도메인으로 풀어내는 것은 카테고리화와 비슷합니다. 예를 들어 'A회원이 B상품을 구매한다'는 문제는 회원과 상품이라는 두 개의 명사와 구매한다라는 동사로 분석할 수 있고, 이는 회원, 상품, 주문, 결제 등으로 상세화할 수 있는데 이것들을 도메인이라고 부릅니다.

 

 

도메인 주도 설계란?

 

도메인 주도 설계는 도메인이 설계를 만든다는 것으로 데이터베이스의 엔터티가 설계를 만드는 것과는 다른 패러다임을 제시하는 개념입니다. 즉, 모델은 데이터베이스의 엔터티를 의미하는 것이 아니라, 요구사항을 담고 있으며, 업무 규칙을 담고 있습니다. 도메인 주도 설계를 하면 유사한 업무끼리 나눠서 설계할 수 있습니다. 주문으로 추상화된 업무들은 주문 도메인에서, 결제로 추상화된 업무들은 결제 도메인에서 설계됩니다. 

 

 

도메인과 객체의 관계

 

도메인과 객체는 어떻게 다르고 둘은 무슨 관계일까요? 객체는 도메인을 표현하는 수단입니다. 객체는 상태, 행동, 식별자를 지니는데 도메인은 객체의 저 3요소로 풀이할 수 있습니다. 또한 객체의 이름을 도메인으로 지어 객체를 도메인으로 부르고 설명할 수 있습니다.

 

 

 

DDD(Domain Driven Design)의 필요성

 

1. 커뮤니케이션의 용이함

 

도메인 주도 설계에서 코드는 도메인을 표현합니다. 따라서 개발자끼리 혹은 개발자와 도메인 전문가끼리의 커뮤니케이션은 이해하기 어려운 코드 상의 용어가 아닌 도메인 용어로 할 수 있습니다. 이 목적을 달성하기 위해 보편 언어(Ubiquitous language)를 사용해야 합니다.

 

- 실천법 -

 

1) 보편 언어는 도메인 전문가, 개발자 모두가 이해할 수 있는 언어입니다. 모델에서부터 보편 언어를 사용합니다. 그리고 모델을 언어의 근간으로 사용해야 합니다. 팀 내 모든 의사소통과 코드에서 해당 언어를 사용합니다.

 

2) 모델을 보편 언어로 표현하므로 보편 언어의 변화는 모델의 변화를 의미합니다. 기획자와 의사소통을 하다가 기존에 사용하던 보편 언어가 변경되었음을 알아챘다면 모델을 수정해야 한다는 것으로 받아들여야 합니다.

 

3) 모델은 높은 수준의 정책에 해당하므로 이것이 변경되면 대부분의 코드를 변경해야 합니다. 보편 언어를 변경하면 그에 맞게 코드에서 해당 네임을 일괄 수정해야 합니다.

 

 

2. 더 좋은 가독성을 가진 코드와 더 쉽게 습득하는 도메인 지식

 

코드를 도메인 용어로 작성하기 때문에 도메인의 지식을 갖출수록 코드를 읽기 편해집니다. 프로젝트 중간에 투입되더라도 해당 도메인 지식을 가지고 있으면 도메인 지식을 기반으로 코드를 읽을 수 있습니다. 또한 코드를 분석하면 동시에 도메인 분석이 되기 때문에 코드 분석만으로도 쉽게 도메인 지식을 습득할 수 있습니다.

 

- 실천법 -

 

1) 위에서 언급했던 보편 언어를 사용합니다. 일관된 네이밍 규칙으로 도메인을 코드로 기술합니다.

 

2) 도메인의 구현을 다른 관심사와 분리합니다. 이를 위해 도메인 계층을 따로 분리합니다. 도메인 계층은 모델이 살아있는 곳입니다. 이곳에서는 업무 개념과 업무 상황에 관한 정보, 업무 규칙을 표현합니다.

 

3) 비즈니스 로직을 구현하는 응용 계층을 도메인 계층과 분리합니다. 이곳에서는 소프트웨어가 수행할 작업을 정의하고 객체가 문제를 해결합니다.

 

도메인에 관련된 코드가 상당한 양의 도메인과 관련이 없는 다른 코드를 통해 널리 확산될 경우 도메인에 관련된 코드를 확인하고 추론하기가 굉장히 힘들어집니다. 따라서 이렇게 도메인 계층을 따로 분리하여 가독성을 키웁니다.

 

도메인 계층은 응용 계층보다 더 높은 수준의 정책을 가지므로 응용 계층은 도메인 계층에 의존하지만 도메인 계층은 응용 계층에 의존하지 않습니다. 의존성 역전 법칙을 지킵니다.

 

4) 반복적인 리팩터링을 합니다. 리팩터링 타이밍은 다음과 같습니다.

 

- 현재 팀에서 도메인을 이해하고 있는 바가 설계에 표현돼 있지 않은 경우
- 중요한 개념이 설계상에 암시적으로 표현돼 있는 경우 (그리고 개념을 명확하게 표현할 수 있는 방법이 보이는 경우)
- 설계상의 중요한 부분을 더욱 유연하게 만들 기회가 보이는 경우

 

 

3. 관심사의 분리

 

도메인 별로 각 개발팀이 업무를 맡아 자신의 도메인만 관심사를 두어 일을 할 수 있습니다. 서로 다른 도메인의 변경사항에 의해 자신이 맡은 도메인에 오류가 발생하지 않도록 결합도를 끊어 인터페이스만 제공하여 모델의 무결성을 유지할 수 있습니다.

 

- 실천법 -

 

1) 제한된 컨텍스트(bounded context)를 사용합니다. 다수의 모델이 사용될 때, 어떤 컨텍스트에서 어떤 모델을 사용해서는 안되는지 코드 기반이나 데이터베이스 스키마와 같은 물리적인 형태에서 명시적으로 정의합니다.

 

2) 하나의 컨텍스트는 하나의 개발팀이 담당합니다. 단, 하나의 개발팀은 여러 개의 컨텍스트를 담당할 수 있습니다.

 

3) 컨텍스트 경계 내에서는 모델을 엄격하게 일관된 상태로 유지하고 경계 바깥의 이슈 때문에 초점이 흐려지거나 혼란스러워져서는 안 됩니다.

 

4) 컨텍스트간의 관계를 그린 컨텍스트 맵(context map)을 그립니다.

 

5) 각 컨텍스트마다 CI/CD를 따로 구축합니다.

 

이 실천법은 마이크로 서비스 아키텍처(MSA)를 하는 것과 같은 방향입니다. MSA는 DDD와 함께 진행하면 더욱 효과적이게 됩니다.

 

 

 

 

 

 

DDD의 진입장벽이 높은 이유

 

1. 애자일 방법론 적용

 

DDD의 전제조건 두 가지가 있습니다. 첫째는 애자일 방법론을 사용하는 것이고, 둘째는 도메인 전문가와 개발자는 서로 긴밀하게 커뮤니케이션해야 한다는 것입니다. 일단 애자일 방법을 사용하는 팀에서의 경험이 없으면 이것이 막연하게 느껴지는 것이 문제입니다.

 

 

2. 설계의 어려움

 

설계는 보통 경력이 풍부한 개발자가 하기 때문에 주니어 개발자들은 설계 자체가 어려워서 DDD까지는 막연하게 느껴지는 것이 문제입니다. 도메인 계층과 제한된 컨텍스트를 제대로 사용하려면 클린 아키텍처에 대한 지식과 SOLID에 대한 이해를 가지고 있어야 합니다.

 

 

3. Aggregate

 

도메인 객체의 생명주기와 관련된 두 가지 문제가 있습니다. 도메인 객체의 무결성을 유지하는 것과 생명주기 관리의 복잡성으로 인해 모델이 난해해지는 것입니다. 이것을 해결하는 방법이 Aggregate, Factory, Repository를 추가하는 것입니다. Aggreate를 모델링하고 설계에 Factory와 Repository를 추가하면 모델 객체의 생명주기 동안 그것들을 체계적이고 의미 있는 단위로 조작할 수 있습니다. 그런데 Aggregate를 설계하기 위해 필요한 기반 지식이 많습니다. 트랜잭션, 엔터티, 불변 객체, 가비지 컬렉션에 대해 이해하고 있어야 합니다.

 

 

 

진입장벽을 극복하는 방법

 

회사에서 적용하기 전에 스스로 개인 프로젝트로 연습해봅니다. 애자일을 혼자서 연습하는 방법은 최소한의 요구사항만 가지고 개발을 마치고, 또 다른 요구사항을 추가하고 그것을 개발하는 사이클을 반복해보는 것입니다. 이것이 반복될 때마다 설계가 변경될텐데, 그 방식에 적응하는 것입니다. 이런 방식에 적응하기 위해 SOLID원칙을 공부하고 계속 적용하려고 노력해봅니다.

 

보편 언어 사용법을 깨닫기 위해 클린 코드에 대한 이해가 있으면 더 좋지만 그렇지 않아도 시작할 수 있습니다. 도메인을 누구나 알아볼 수 있는 이름으로 작명하는 것을 먼저 해봅니다. 그리고 그것으로 모든 클래스, 객체, 메서드 등 코드 네이밍에 적용합니다.

 

소프트웨어 개발 철학과 관련된 수많은 개념이 DDD로부터 파생되었습니다. 사실 그런 것들을 공부하다 보면 알게 모르게 DDD에 젖어들고 있는 것입니다. TDD, 클린 코드, 클린 아키텍처, 리팩터링, 객체지향 프로그래밍 등을 먼저 공부해보고 오면 더 넓은 시야로 DDD를 바라볼 수 있습니다.

 

이 포스트에서 DDD에 대해 더 많은 구체적인 내용을 다루지는 못했습니다. 하지만 이 글로 인해 조금이라도 DDD에 대해 쉽고 편하게 느껴지시면 좋겠다는 생각입니다. DDD에 대해 깊게 공부하려면 에릭 에반스도메인 주도 설계를 읽어보시기를 추천해드립니다.

 

도메인 주도 설계:소프트웨어의 복잡성을 다루는 지혜, 위키북스

 

(이 포스팅은 쿠팡 파트너스 활동의 일환으로, 이에 따른 일정액의 수수료를 제공받습니다.)

 

 

 

  • 네이버 블러그 공유하기
  • 네이버 밴드에 공유하기
  • 페이스북 공유하기
  • 카카오스토리 공유하기