백엔드 프레임워크

[아키텍처] 도메인 주도 설계(DDD)

ioh'sDeveloper 2025. 1. 5. 17:09

도메인 주도 설계(DDD) 개요

1. 도메인

소프트웨어 개발에서 "도메인"은 소프트웨어가 해결하고자 하는 문제 영역이나 비즈니스 영역을 의미합니다. 도메인은 특정 비즈니스의 핵심 개념, 규칙, 프로세스를 포함합니다.

예를 들어, 은행 시스템에서는 계좌, 고객, 거래와 같은 개념이 도메인에 해당하며, 이러한 요소들에 대한 비즈니스 규칙이 포함됩니다. 도메인에 대한 이해는 비즈니스 문제를 효과적으로 해결할 수 있는 소프트웨어를 개발하는 데 필수적입니다.

도메인의 주요 특징:

  • 비즈니스 중심: 실제 비즈니스 문제와 요구사항에 중점을 둡니다.
  • 고유한 용어: 비즈니스 커뮤니케이션에서 필수적인 특정 용어와 정의를 포함합니다.
  • 핵심 로직: 비즈니스 규칙과 로직이 도메인의 핵심에 위치하며 소프트웨어에 반영되어야 합니다.

2. 도메인 패턴

도메인 패턴은 도메인 내에서 반복적으로 발생하는 문제를 해결하기 위한 설계 패턴입니다. 이러한 패턴을 사용하면 소프트웨어의 유지보수성과 확장성을 높이고 복잡성을 줄일 수 있습니다.

주요 도메인 패턴:

  • 리포지토리 패턴: 도메인 객체의 영속성과 조회를 관리합니다.
  • 명세 패턴: 비즈니스 규칙과 조건을 캡슐화하여 데이터 검색을 간소화합니다.
  • 애그리게이트 패턴: 관련 엔티티와 값 객체를 하나의 단위로 묶어 관리합니다.
  • 도메인 이벤트 패턴: 도메인 내에서 발생하는 중요한 사건을 캡처하고 전파합니다.

도메인 패턴을 활용하면 비즈니스 요구사항에 맞는 유연한 소프트웨어를 개발할 수 있습니다.


3. 소프트웨어 아키텍처의 레이어

레이어드 아키텍처는 소프트웨어 시스템을 서로 다른 역할과 책임을 가진 레이어로 나누는 방식입니다. 각 레이어는 특정 기능을 담당하며, 시스템의 모듈성과 유지보수성을 높입니다.

전형적인 레이어 구성:

  • 프레젠테이션 레이어: 사용자 인터페이스와 상호작용을 처리합니다.
  • 비즈니스 레이어: 핵심 비즈니스 로직을 포함합니다.
  • 영속성 레이어: 데이터 저장 및 조회를 관리합니다.

시스템을 레이어로 나누면 각 레이어의 변경이 다른 레이어에 미치는 영향을 최소화할 수 있습니다.


4. 도메인 주도 설계(DDD)의 목표

도메인 주도 설계는 도메인 모델을 중심으로 소프트웨어를 설계하고 개발하는 방법론입니다. DDD의 주요 목표는 비즈니스 도메인의 복잡성을 이해하고 이를 소프트웨어 모델에 반영하여 문제를 해결하는 것입니다.

DDD의 주요 목표:

  1. 도메인 모델 중심 설계: 도메인 모델을 소프트웨어 설계의 중심에 둡니다.
  2. 보편적 언어(Ubiquitous Language) 사용: 개발자와 도메인 전문가 간의 원활한 의사소통을 위해 공통된 언어를 사용합니다.
  3. 복잡성 관리: 구조화된 접근 방식을 통해 복잡한 비즈니스 규칙을 관리합니다.
  4. 소프트웨어 품질 향상: 도메인 모델 기반의 설계를 통해 코드 품질과 유지보수성을 향상시킵니다.

5. DDD의 핵심 기둥

DDD는 도메인 중심 시스템 설계를 지원하는 세 가지 주요 기둥을 기반으로 합니다.

1. 도메인 모델링:

  • 도메인 모델링은 비즈니스의 주요 개념, 규칙, 프로세스를 정의하고 이해하는 과정입니다.
  • 도메인 전문가와 개발자가 협력하여 도메인의 핵심 개념을 도출하고 이를 모델로 표현합니다.

2. 전략적 설계:

  • 대규모 시스템의 복잡성을 관리하기 위한 고수준의 설계를 다룹니다.
  • 서브도메인(Subdomain), 바운디드 컨텍스트(Bounded Context), 컨텍스트 매핑(Context Mapping)과 같은 개념을 사용하여 시스템을 구조화합니다.

3. 전술적 설계:

  • 도메인 모델을 코드로 구현하는 구체적인 방법론을 제공합니다.
  • 엔티티(Entity), 값 객체(Value Object), 애그리게이트(Aggregate), 리포지토리(Repository), 도메인 이벤트(Domain Event)와 같은 패턴을 적용하여 일관된 코드 구조를 만듭니다.

6. DDD의 주요 개념

서브도메인(Subdomain):

서브도메인은 전체 도메인을 특정 비즈니스 영역으로 나눈 것입니다. 각 서브도메인은 고유한 비즈니스 문제와 요구사항을 해결합니다.

  • 핵심 서브도메인: 비즈니스의 핵심 가치를 제공하는 영역으로, 개발 우선순위가 높습니다.
  • 지원 서브도메인: 핵심 서브도메인을 지원하지만 비즈니스에 고유하지는 않습니다.
  • 일반 서브도메인: 공통적인 문제를 다루며, 종종 서드파티 솔루션으로 해결됩니다.

바운디드 컨텍스트(Bounded Context):

바운디드 컨텍스트는 특정 도메인 모델이 유효한 경계를 정의합니다. 각 바운디드 컨텍스트는 고유한 모델과 용어를 가지며, 서로 다른 컨텍스트 간에는 의미가 다를 수 있습니다.

컨텍스트 매핑(Context Mapping):

컨텍스트 매핑은 서로 다른 바운디드 컨텍스트 간의 관계를 정의합니다. 이를 통해 서로 다른 도메인 모델을 사용하는 시스템 간의 통합을 관리합니다.

주요 컨텍스트 매핑 패턴:

  • 공유 커널(Shared Kernel): 여러 컨텍스트에서 공통으로 사용하는 모델의 일부.
  • 고객/공급자(Customer/Supplier): 한 컨텍스트가 다른 컨텍스트에 의존하는 관계.
  • 안티코럽션 레이어(Anti-Corruption Layer): 서로 다른 모델 간의 변환을 처리하여 부정적인 영향을 방지하는 보호 계층.

7. 협업 모델링(Collaborative Modeling)

협업 모델링은 도메인 전문가와 개발자가 함께 도메인 모델을 개발하는 과정입니다. 이 과정은 도메인에 대한 깊은 이해를 바탕으로 소프트웨어 모델을 구축하는 데 중점을 둡니다.

협업 모델링의 주요 원칙:

  • 도메인 전문가와의 협력: 도메인 전문가와 개발자가 함께 도메인 모델을 설계합니다.
  • 보편적 언어 사용: 공통된 언어를 사용하여 의사소통 오류를 줄입니다.
  • 반복적 개발: 지속적인 피드백을 통해 모델을 점진적으로 개선합니다.
  • 지식 공유: 개발자가 비즈니스 도메인에 대해 지속적으로 학습하고 이를 팀과 공유합니다.

8. DDD의 전술적 설계

전술적 설계는 도메인 모델을 코드로 구현하는 구체적인 방법을 제공합니다. 이를 통해 소프트웨어 시스템의 일관성과 유연성을 유지할 수 있습니다.

전술적 설계의 주요 패턴:

  • 엔티티(Entity): 고유한 식별자를 가진 객체 (예: 고객, 주문).
  • 값 객체(Value Object): 고유한 식별자가 필요 없는 객체로 값만을 표현 (예: 주소, 금액).
  • 애그리게이트(Aggregate): 관련된 엔티티와 값 객체를 하나의 단위로 묶어 관리.
  • 리포지토리(Repository): 도메인 객체의 저장소 역할을 하는 추상화 계층.
  • 팩토리(Factory): 복잡한 객체 생성을 담당하는 패턴.

Java 코드 예제:

엔티티와 값 객체:

// 엔티티: 주문(Order)
public class Order {
    private Long id;
    private Customer customer;
    private List<OrderLine> orderLines;

    public Order(Long id, Customer customer, List<OrderLine> orderLines) {
        this.id = id;
        this.customer = customer;
        this.orderLines = orderLines;
    }
}

// 값 객체: 주문 항목(OrderLine)
public class OrderLine {
    private Product product;
    private int quantity;

    public OrderLine(Product product, int quantity) {
        this.product = product;
        this.quantity = quantity;
    }
}

애그리게이트 예제:

public class Order {
    private Long id;
    private Customer customer;
    private List<OrderLine> orderLines;

    public void addOrderLine(Product product, int quantity) {
        this.orderLines.add(new OrderLine(product, quantity));
    }

    public BigDecimal calculateTotal() {
        return orderLines.stream()
            .map(line -> line.getProduct().getPrice().multiply(BigDecimal.valueOf(line.getQuantity())))
            .reduce(BigDecimal.ZERO, BigDecimal::add);
    }
}

9. 요약

도메인 주도 설계(DDD)는 비즈니스 도메인을 이해하고 이를 소프트웨어에 반영하여 복잡한 문제를 해결하는 강력한 방법론입니다. 전략적 설계와 전술적 설계 원칙을 적용하면 유지보수 가능하고 확장 가능한 시스템을 구축할 수 있습니다.

서브도메인, 바운디드 컨텍스트, 컨텍스트 매핑과 같은 개념을 통해 시스템의 복잡성을 구조적으로 관리하며, 협업 모델링을 통해 비즈니스 요구사항과 개발자 간의 간극을 줄일 수 있습니다.