도메인 주도 개발(Domain-Driven Design, DDD)은 복잡한 소프트웨어 시스템을 개발할 때 도메인의 비즈니스 로직과 요구사항에 중점을 두고 설계하는 접근 방식입니다. DDD는 도메인의 전문가(비즈니스 사용자)와 개발자가 긴밀하게 협력하여, 소프트웨어가 도메인을 올바르게 표현하고 유지보수하기 쉽게 만드는 것을 목표로 합니다. Eric Evans가 그의 책 Domain-Driven Design: Tackling Complexity in the Heart of Software에서 소개한 개념으로, DDD는 특히 복잡한 비즈니스 도메인을 다루는 대규모 시스템에서 효과적입니다.
DDD는 주로 다음과 같은 개념에 기반합니다:
도메인은 비즈니스나 애플리케이션이 작동하는 특정 문제 영역을 말합니다. 예를 들어, 은행 시스템에서 도메인은 금융 거래, 고객 관리, 대출 처리와 같은 개념들로 구성될 수 있습니다.
도메인 모델은 도메인의 개념들을 표현한 추상적인 모델로, 시스템 내에서 비즈니스 로직을 캡슐화합니다. 이 모델은 비즈니스 전문가와 개발자가 공유하는 용어와 개념을 반영하여 도메인을 이해하고 표현할 수 있도록 도와줍니다.
개발자와 비즈니스 전문가가 동일한 언어를 사용하는 것을 말합니다. 즉, 코드, 문서, 대화에서 사용하는 용어가 모두 일관성이 있어야 합니다. 이를 통해 의사소통의 혼선을 줄이고, 모델이 비즈니스 요구사항과 밀접하게 연관되도록 합니다.
복잡한 도메인을 작은 하위 도메인으로 나누어 각각의 모델을 독립적으로 설계할 수 있도록 합니다. 각 하위 도메인마다 독립된 모델과 용어 체계를 가질 수 있으며, 이 모델들은 컨텍스트 경계로 명확히 구분됩니다. 컨텍스트 경계는 각 도메인이 격리되어야 할 지점을 나타내고, 모델 간의 상호작용을 명확히 정의하는 데 도움을 줍니다.
고유한 식별자를 가진 객체로, 도메인에서 중요하게 취급되는 개념입니다. 예를 들어, "사용자", "계좌" 등이 엔티티일 수 있으며, 시간에 따라 상태가 변경될 수 있습니다.
엔티티와 달리 식별자를 가지지 않고, 주로 불변성을 갖는 객체입니다. 예를 들어, "주소"나 "날짜" 등이 값 객체가 될 수 있습니다. 값 객체는 엔티티에 속할 수 있지만 그 자체로 식별되지 않습니다.
여러 엔티티와 값 객체를 하나의 단위로 묶어 일관성 있게 관리하는 구조입니다. 애그리게잇은 외부에서 직접 접근할 수 없으며, 항상 루트 엔티티(Aggregate Root)를 통해서만 접근할 수 있습니다. 예를 들어, "주문" 애그리게잇은 주문 자체와 그 안에 포함된 여러 상품 목록 엔티티로 구성될 수 있습니다.
엔티티나 애그리게잇을 영속성 계층에서 불러오고 저장하는 역할을 담당합니다. 리포지토리는 애그리게잇을 저장하거나 조회하는 인터페이스를 제공하며, 데이터베이스와 도메인 로직 간의 추상적인 연결고리 역할을 합니다.
특정 도메인 로직을 구현하는 객체입니다. 서비스는 엔티티나 값 객체와 관련된 로직을 처리하지 않으며, 특정 작업이나 비즈니스 규칙을 처리하는 데 중점을 둡니다. 일반적으로 상태를 갖지 않고, 비즈니스 로직을 구현하기 위한 도메인 서비스와 애플리케이션 전반에 걸친 기능을 제공하는 애플리케이션 서비스로 나뉩니다.
복잡한 객체나 애그리게잇을 생성하는 책임을 맡는 패턴입니다. 애그리게잇의 생성 로직이 복잡할 경우 팩토리를 통해 이를 단순화할 수 있습니다.
DDD의 적용은 다음과 같은 과정으로 진행될 수 있습니다:
도메인 분석 및 설계
유비쿼터스 언어 확립
컨텍스트 경계 설정
도메인 객체 구현
도메인 이벤트 처리
도메인 주도 개발은 비즈니스 도메인의 복잡성을 해결하는 데 중점을 둔 소프트웨어 설계 방법론으로, 복잡한 시스템에서도 유지보수성과 확장성을 높이는 데 매우 유용한 방식입니다. DDD는 비즈니스 전문가와의 협업을 강조하고, 이를 통해 소프트웨어가 비즈니스 요구사항을 정확히 반영할 수 있도록 도와줍니다.