Skip to main content

Hexagonal


danger

DDD를 적용하는 것이 항상 좋은것은 아닙니다.

CRUD만으로 해결되지 않는 경우, 복잡한 사용자 스토리, 잦은 변경 및 기능 추가, 팀원 모두 생소한 도메인 등 여러 조건에 따라 필요한 곳에 부분적으로 적용하는 것이 좋습니다.

자세한 내용은 Refactoring에서 다룹니다.

Domain Layer

Application Layer

  • 시그니처의 구성은 아래 세 경우로 나뉩니다
    • 도메인 객체를 포함하는 경우
    • 원시 타입, String, DTO만 을 사용하는 경우
    • Command 객체를 사용하는 경우
  • 영속성 트랜잭션 제어를 할 수 있습니다
  • 인증, 인가 제어를 할 수 있습니다
  • Noti, Publish, Email 전송 등을 할 수 있습니다
  • 서비스 자체의 상태는 갖지 않습니다

Usecase

도메인 객체를 사용하여 특정 시나리오를 수행하는 것을 사용자 시나리오(Usecase)라고 합니다.

자주 등장하는 흐름 아래와 같습니다.

  1. 리포지터리에서 엔티티 또는 애그리거트를 얻어옵니다.
  2. 도메인 서비스, 애그리거트, 엔티티 등을 사용하여 일련의 도메인 논리를 수행합니다.
  3. 리포지터리를 사용하여 변경사항을 저장합니다.
  4. 에러가 발생한 경우 User Interface에서 처리할 수 있는 방법을 노출시켜줍니다.

Application Service

도메인 객체와 상관없이 애플리케이션의 편의를 위해 제공되는 기능들을 애플리케이션 서비스(Application Service)라고 합니다.

User Interface Layer(Primary/Driving Adapter)

1차 어댑터의 시그니처는 HTTP, gRPC, CLI 등 외부 요청에 맞춰 작성되어야 합니다.

Infrastructure Layer(Secondary/Driven Adapter)

Directory Structure

디렉토리, 파일 명은 의미에 맞게 변경될 수 있습니다. 중요한 점은 처음부터 아래와 같은 구성을 갖는 것이 아닙니다. 프로그램이 커지고 복잡해질 때, 리팩토링 과정을 거치게 되면서 아래와 같은 구조가 됩니다.

bounded_context/
├── domain/
│ ├── event/
│ │ ├── event_1.go
│ │ └── ...
│ ├── factory/
│ │ ├── entity_1.go
│ │ └── ...
│ ├── repository/ # 인터페이스
│ │ ├── entity_1.go
│ │ └── ...
│ ├── service/ # 비지니스 로직 구현 or 외부 서비스에 대한 인터페이스
│ │ ├── service_1.go
│ │ ├── publisher_1.go
│ │ └── ...
│ ├── valueobject/
│ │ ├── valueobject_1.go
│ │ ├── valueobject_2.go
│ │ └── ...
│ ├── entity_1.go # 애그리거트 루트도 여기에 위치
│ ├── entity_2.go
│ └── ...
├── application/
│ ├── service/
│ └── usecase/
│ ├── usecase_1.go
│ └── ...
├── infrastructure/
│ ├── service/
│ ├── orm/
│ │ ├── dao/
│ │ │ ├── dao_1.go
│ │ │ └── ...
│ │ └── client.go
│ ├── repository/
│ │ ├── entity_1.go
│ │ └── ...
│ └── ...
└── user_interface/
├── rest/
│ ├── dto/
│ │ ├── dto_1.go
│ │ └── ...
│ ├── controller/
│ │ ├── controller_1.go
│ │ └── ...
│ └── ...
├── cli/
└── ...
  • domain 디렉토리 내의 코드는 domain 내에서만 의존성을 가질 수 있습니다
  • application 디렉토리 내의 코드는 domain, application 내에서만 의존성을 가질 수 있습니다
  • infrastructure 디렉토리 내의 코드는 인터페이스에 대한 구현이므로 domain, application에 의존성을 갖습니다
  • user_interface 디렉토리 내의 코드는 다양한 의존성을 가질 수 있습니다

Reference