kongkong.note

[도메인 주도 개발 시작하기] 2. 아키텍처 개요 본문

DDD

[도메인 주도 개발 시작하기] 2. 아키텍처 개요

hyokong 2025. 12. 15. 23:57

2.1 네 개의 영역

표현 영역 : 요청 <-> 응용 영역 형태 변환

응용 영역 : 도메인 영역의 도메인 모델을 사용하여 기능 구현. 도메인 모델에 로직 수행을 위임

도메인 영역 :  도메인 모델(도메인의 핵심 로직 구현) 구현

인프라스트럭처 영역 : 구현 기술 다룸(DB 연동, 메시징 큐 ...)

 

2.2 계층 구조 아키텍처

아키텍처의 계층 구조 : (상위, 고수준) 표현 -> 응용 -> 도메인 -> 인프라스트럭처 (하위, 저수준)
ㄴ 바로 아래 계층에만 의존을 가지는 것은 아니고, 하위 계층에 유연하게 의존성 적용

인프라스트럭처 영역에 너무 의존하면 1. 테스트 어려움 2. 기능 확장의 어려움 문제 발생 => DIP 활용

 

2.3 DIP

DIP(Dependency Inversion Princlple) 의존 역전 원칙 : 추상화 인터페이스를 사용하여 저수준 모듈이 고수준 모듈에 의존하도록 바꾸는 것
ㄴ 추상화 인터페이스는 고수준 모듈 관점에서 도출해야 한다.

❌ 잘못된 추상화 예시

[구조]
infra/payment/PayClient.java   ← 인터페이스
domain/OrderService.java

// infra/payment/PayClient.java
interface PayClient {
    void pay(int amount);
}
// infra/payment/KakaoPayClient.java
class KakaoPayClient implements PayClient {
    public void pay(int amount) {
        System.out.println("카카오페이 결제");
    }
}
// domain/OrderService.java
class OrderService {

    private final PayClient payClient = new KakaoPayClient();
    // 🔴 타입은 인터페이스지만, 생성에서 저수준 구현에 직접 의존

    void order() {
        payClient.pay(1000);
    }
}

✅ 올바른 추상화 예시

[구조]
domain/PayProcessor.java   ← 인터페이스
infra/payment/KakaoPayProcessor.java
domain/OrderService.java

// domain/PayProcessor.java
interface PayProcessor {
    PayResult process(Money amount);
}
// infra/payment/KakaoPayProcessor.java
class KakaoPayProcessor implements PayProcessor {
    public PayResult process(Money amount) {
        // 카카오페이 SDK 호출
        return PayResult.success();
    }
}
// domain/OrderService.java
class OrderService {
    private final PayProcessor payProcessor;

    OrderService(PayProcessor payProcessor) {
        this.payProcessor = payProcessor;
    }

    void order() {
        PayResult result = payProcessor.process(new Money(1000));
        if (result.isSuccess()) {
            // 주문 완료
        }
    }
}

 

2.4 도메인 영역과 주요 구성요소

엔티티(ENTITY) : 고유의 식별자를 갖는 객체

밸류(VALUE) : 고유의 식별자를 갖지 않는 객체로, 주로 개념적인 하나의 값을 표현할 때 사용(ex_ 주소). 불변 객체.

애그리거트(AGGREGATE) : 연관된 엔티티와 밸류 객체를 개념적으로 하나로 묶은 것. root 엔티티를 갖는다.

리포지터리(REPOSITORY) : 도메인 모델의 영속성 처리(DBMS 로딩, 저장 ..). save, findById.. 기본 제공 엔티티 있음.

도메인 서비스(DOMAIN SERVICE) : 특정 엔티티에 속하지 않은 도메인 로직 제공(여러 엔티티와 밸류를 필요로 하는 로직 구현)