DDD라는 개념이 어떤 것인지 간단하게 훑어보고자 합니다.


DDD(Domain-Driven Design)

2003년 Eric Evans의 책 DDD에서 처음 등장한 이 개념은 소프트웨어 개발 접근 방식 중 하나로, 아래의 사항들을 만족해야 합니다.

  • 프로젝트의 주요 관심사를 핵심 관심사로 초점을 맞춘다.
  • 도메인 실무자들과 소프트웨어 개발자들의 협업이 가능하도록 한다.
  • Bounded Context 안에서 유비쿼터스 언어로 소통한다.

여기까지만 보면 무슨 내용인지 이해가 잘 가지 않습니다. 도메인은 무엇이고, Bounded Context? 유비쿼터스 언어? 너무 생소한 개념들이 많습니다.


DDD를 한마디로 정의하자면 비즈니스 도메인을 중심으로 소프트웨어를 구축하는 방법론입니다.

이 문장을 생각하면서 좀 더 깊게 생각해봅시다.

비즈니스 도메인이란?

도메인이라는 단어의 의미는 여러가지가 존재하지만, DDD에서 말하는 도메인은 비즈니스 도메인을 의미합니다.

비즈니스 도메인이란 문제 해결을 하려는 분야, 해당 비즈니스 영역입니다. 예를 들어 회원가입, 로그인, 회원 탈퇴와 같은 기능을 구현할 때 도메인은 회원이라고 할 수 있습니다.

우아콘에서 박재성님이 자세히 설명해주신 강의가 있어 참고하셔도 좋을 것 같습니다.
https://www.youtube.com/watch?v=kmUneexSxk0

따라서 DDD는 비즈니스 도메인 안으로만 관심사를 묶어 결합도는 낮추고 응집성을 높이는, 어찌보면 OOP스러운 방법론이라고도 볼 수 있을 것 같습니다.



이번에는 구축하는 방법을 보겠습니다. DDD의 설계는 크게 2가지 흐름, 전략적 설계구체적 설계로 진행됩니다.

전략적 설계(Strategic Design)

전략적 설계는 Bounded Context를 구성하고, 각 Context마다 유비쿼터스 언어를 사용하여 도메인 모델을 구축하는 과정입니다.

Bounded Context

출처: 링크

도메인 모델링을 위해 도메인을 작은 단위로 분할하는 것입니다. 각 컨텍스트는 경계를 가지고, 그 안에서는 일관된 언어, 개념 및 모델을 사용합니다. 위의 그림에서처럼 제조와 관련된 부분들과, 판매와 관련된 부분들을 나눌 수 있을 것입니다.

핵심은 각 Bounded Context마다 어떤 용어에 대해 다르게 이해할 수 있지만, Bounded Context 내부에서 어떤 용어는 그 누구가 보더라도 동일한 의미로 이해되어야 합니다.

예를 들어 기수라는 단어를 들었을 때, 경마장이라는 Context에서는 말을 타는 사람이겠지만, 전쟁이라는 Context에서는 깃발을 드는 사람이라고 해석될 수 있습니다. 하지만 하나의 Context 내부에서만큼은 다른 의미의 기수가 존재하면 안됩니다.


이러한 용어는 Ubiquitous Language를 통해 작성되어야 합니다.

Ubiquitous Language

클래스명, 변수, 모듈 등에서 도메인 전문가와 개발자가 공유하는 공통 언어입니다. 이는 도메인에 대한 이해를 향상시키고 의사소통을 편리하게 도와줍니다.

도메인 전문가는 기획자 뿐만 아니라 실제 사용할 사용자들도 모두 포함되는 개념입니다.

개발자가 예를 들어 엔티티타입명을 EntityDDD1과 같이 자신들만 아는 언어로 만든다면, 도메인 전문가는 이해하지 못할 것입니다.

Context Map


출처: 링크

각 Context의 설계를 마쳤으면, 서로 매핑을 하여 설계를 완성해야 합니다. Context경계에서 일어나는 상호작용을 선으로 연결하는 작업까지 진행하면 Strategic Design은 완성입니다.




전술적 설계(Tactical Design)

앞선 전략적 설계가 Bounded Context간 연결이 핵심이였다면, 전술적 설계는 좀 더 세부적으로 들어와 Bounded Context 내부의 구체적인 설계입니다.

전술적 설계에서 중요한 개념들은 아래와 같습니다.

엔티티(Entity)

public class Breed {

    @Id
    private Long id;
    private String breedName;
}

엔티티는 도메인 내에서 유일하게 식별가능한 객체입니다. 고유한, 변하지 않는 식별자를 가지고 있지만, 그 외에 attribute는 가변성(mutable)입니다.


값객체(VO, Value Object)

식별자가 없는 개체로, 주로 도메인의 특성이나 속성을 나타냅니다. 불변성(Immutable)을 가지며 동등성을 기반으로 비교됩니다. 따라서 레코드 간 구별은 필요가 없습니다.


집합체(Aggregate)

연관된 엔티티나 VO들을 하나로 묶은 것으로, Root Entity를 가집니다. 복잡한 연관에서 엔티티와 VO만 가지고는 일관성을 유지할 수 없기 때문에 Aggregate가 필요합니다.


팩토리(Factories)

클라이언트가 내부 로직을 모르고도 엔티티나 집합체를 만들 수 있도록 해주는 틀. 팩토리를 통해 도메인을 깔끔하게 관리하고 경계를 쉽게 유지할 수 있습니다.




정리

거창한 것 같지만, 결국은 정해진 형식이라기보다는 어떻게 해야 스파게티 코드가 되지 않고 의존성이 역전되지 않는 깔끔한 설계가 될 수 있을지에 대한 고민이라는 것이 좀 더 맞는 비유일 것 같습니다.

제 나름의 정리로 DDD는 "발생할 수 있는 모든 기능을 보며 적절하게 그룹화하고, 이를 매핑한 다음, 그룹화된 도메인들의 내부를 설계한 다음에 구현을 하자"라고 생각합니다.

DDD와 관련해 카카오 추천팀에서 DDD를 적용한 사례를 제이님의 기술블로그에서 자세하게 기술되어 있으니 참고하시면 좋을 것 같습니다.
https://tech.kakao.com/2022/12/12/ddd-of-recommender-team/





참고자료

https://medium.com/@ruxijitianu/summary-of-the-domain-driven-design-concepts-9dd1a6f90091
https://blog.naver.com/PostView.naver?blogId=seek316&logNo=222710251462
https://yoonbing9.tistory.com/121
https://steemit.com/kr/@frontalnh/domain-driven-design

profile
Backend Engineer

0개의 댓글

관련 채용 정보