최근에 자주 사용된다는 DDD에 대해 궁금해져서 유튜브를 보다가 정리해 두면 좋을 것 같아 정리해보려 한다.
DDD
Domain-Driven Design(DDD)은 소프트웨어 개발에서 복잡한 도메인(비즈니스 영역)을 이해하기 위한 접근 방법이다.
이는 소프트웨어 시스템의 핵심 영역인 도메인에 집중하여, 도메인의 복잡성을 해결하고 도메인 전문가와 개발자들 사이의 협력을 촉진하는 방법론이다.
이 방법은 Eric Evans가 "Domain-Driven Design: Tackling Complexity in the Heart of Software"라는 책에서 소개하였다. DDD의 개념은 그전에도 다양한 형태로 존재했으며, Eric Evans는 이러한 아이디어들을 정리하여 책으로 발행하였다. 이후 DDD는 소프트웨어 개발 커뮤니티에서 확산되며 많은 개발자들과 기업들이 채택하고 있다.
Domain Driven Design
- 비즈니스 Domain 별로 나누어 설계 하는 방식이다.
DDD에서는 기존의 협업에서 IT로의 일방향 소통구조를 탈피하여 현업과 IT의 쌍방향 커뮤니케이션을 매우 중요하게 생각한다. (이 방법은 애자일 기법과 매우 연관이 있다) - DDD의 핵심 목표는 "Loosly coupling", "High cohesion"
느슨한 결합으로 의존성을 최소화하여 상호 간에 영향을 덜 주고, 유연한 재사용 가능한 코드를 만드는 것.
높은 응징도로 소프트웨어의 한 모듈 또는 클래스가 하나의 목적 또는 책임을 가지고, 관련된 기능들을 함께 묶어서 구성하는 것 - DDD는 크게 Strategic Design과 Tactical Desgin으로 나눌 수 있다.
Strategic Design은 전략적 설계이고 Tactical Design은 프로그래밍하기 위한 구체적 설계라고 할 수 있다.
Strategic Design
비즈니스 도메인의 복잡성을 이해하고 다양한 도메인 요소들을 효과적으로 조직화하는 것을 목표로 한다. 이를 위해 Bounded Context, Context Map, Shared Kernel 등의 개념을 사용하여 도메인을 구분하고 의사소통을 원활하게 한다.
- Bounded Context
- DDD에서 도메인을 한정된 경계로 구분하는 개념이다. 각 Bounded Context는 자체적인 유비쿼터스 언어를 가지고 있으며, 도메인 모델을 표현하는데 필요한 요소들을 포함한다. 이는 큰 규모의 프로젝트에서 도메인의 복잡성을 다루는데 도움이 된다.
- Context Map
- Context Map은 Bounded Context 간의 관계와 상호작용을 나타내는 지도이다. 서로 다른 Bounded Context들이 어떻게 연결되어 있는지를 보여주며, 컨텍스트 간의 경계를 명확히 하고 의사소통을 원활하게 한다.
- Shared Kernel (공유 커널)
- Shared Kernel은 두 개 이상의 Bounded Context가 함께 사용하는 중요한 핵심 모델과 규칙을 의미한다. 이를 통해 서로 다른 Bounded Context 간의 중복을 최소화하고, 공통된 부분을 효율적으로 관리한다.
- Ubiquitous Language
- 모델링을 위해 도메인 전문가와 개발자들 사이에서 공통된 언어를 사용하는 것이 중요하다. 이를 유비쿼터스 언어라고 한다.
- 도메인 전문가와 개발자들은 동일한 용어를 사용하여 협력하고, 이해관계를 높이는데 도움이 된다.
- Domain
- 사전적의미는 '영역', '집합'을 뜻한다.
- DDD에서 말하는 Domain은 비즈니스 Domain 이다.
- 비즈니스 Domain은 유사한 업무의 집합이다.
- 애플리케이션은 비즈니스 Domain별로 나누어 설계 및 개발될 수 있다.
- Model
- DDD에서는 복잡한 도메인을 이해하기 쉽고 유지보수하기 쉬운 형태로 모델링을 하는 것이 중요하다.
- 모델은 도메인에 대한 개념과 비즈니스 규칙, 관계, 행위 등을 포함한다.
Tactical Design
Tactical은 프로그래밍하기 위한 구체적인 설계를 다루며, Aggregate, Entity, Value Object, Repository, Domain Service 등의 개념을 사용하여 도메인 모델을 구성한다.
- Aggregate
- 애그리거트는 하나 이상의 관련된 개념을 묶어서 하나의 단위로 취급하는 개념이다. 일반적으로 애그리거트는 하나의 루트(Entity)와 그에 속하는 여러 개의 관련된 객체로 구성된다.
- 일관성을 보장하고 데이터 변경을 관리하는 데 사용된다. 애그리거트 루트는 외부에서 직접 접근 가능하며, 내부의 다른 객체들은 루트를 통해서만 접근이 가능하다.
- 도메인 모델을 단순화하고 복잡성을 제어하는데 도움이 됩니다.
- Entity
- 고유한 식별자를 가지는 도메인 객체로서 변경 가능한 개념. 엔티티는 식별자를 기반으로 동일성을 판단하고 비교된다.
- 애그리거트 내에서 각각의 개별적인 객체로 존재하며, 고유한 식별자를 통해 동일성을 유지한다.
- 데이터베이스 테이블과 일치하는 개념이며, 주로 영속성을 가지고 데이터베이스에 저장되거나 조회된다.
- Value Object
- 변경 불가능한(Immutable) 개념으로서 식별자 대신에 속성들의 조합으로 동일성을 판단한다. 값 객체는 불변성을 유지하기 때문에 값을 복사하는 것이 안전하다.
- 애그리거트 내에서 복잡한 개념의 속성을 표현하거나, 도메인의 개념적인 부분을 표현하는 데 사용된다.
- 데이터베이스 테이블과 매핑되지 않으며, 엔티티나 애그리거트의 일부로써 존재한다.
- Repository
- Data access를 처리하는 객체이다.
- Aggregate, Entity를 위해 데이터 CRUD를 담당한다.
- 실제 구현시에는 ORM을 쓰는 것이 가장 이상적이다.
- Domain Service
- 도메인 객체의 행위와 관련된 로직을 처리하는 서비스를 의미한다.
- Repository와는 다르게 상태를 가지지 않으며, 주로 도메인 객체 간의 복잡한 로직을 분리하는 데 사용된다.
출처:
마이크로서비스 개발을 위한 Domain Driven Design - 정말 이해하기 쉽게 설명해 주신다.
DDD 핵심 원리 - 위에 것 보고 이걸 보면 이해하기 훨씬 쉬울 것 같다.
'Spring' 카테고리의 다른 글
[Spring] JUnit을 이용한 단위 테스트, 통합 테스트 (0) | 2023.09.20 |
---|---|
단위 테스트, 통합 테스트 (0) | 2023.09.14 |
프로젝트 패키지 구조는 어떻게 나누는게 좋을까 (0) | 2023.07.14 |
[Spring] 왜 Service 와 ServiceImpl로 나누는걸까 (0) | 2023.06.28 |
OAuth (0) | 2023.05.06 |