이직 공고를 찾아보다가 "DDD에 대한 이해를 바탕으로 아키텍처 설계 및 구현 가능하신 분"이라는 문구를 발견했다.
그런데 DDD가 뭐지? 궁금해서 가볍게 공부해보았다.
DDD란?
DDD(Domain-Driven Design, 도메인 주도 설계)는 말 그대로 도메인(업무 영역)을 중심으로 개발하는 방식이다. 쉽게 말해, "비즈니스 로직을 객체에 내재화하여 관리하는 방법"이라고 볼 수 있다.
보통 웹 개발을 할 때, 우리는 데이터를 저장하고 불러오는 데 집중하는 경우가 많다. 그런데 서비스가 커지고 비즈니스 로직이 복잡해질수록, 데이터 중심 설계는 유지보수가 어려워진다. 여기서 등장하는 개념이 DDD다.
기존 방식 vs DDD 방식
기존의 웹 개발에서는 **심판(서비스 계층)**이 모든 게임 규칙을 관리하고, **유저(객체)**는 단순한 데이터 덩어리였다. 예를 들어, 1:1 격투 게임에서 전투 로직을 구현한다고 가정해보자.
❌ 기존 방식 (서비스 중심 설계)
public class GameService {
public void attack(Player attacker, Player defender) {
if (defender.getHp() <= 0) {
throw new IllegalStateException("이미 죽은 플레이어를 공격할 수 없습니다.");
}
int damage = attacker.getAttackPower();
defender.setHp(defender.getHp() - damage);
}
}
서비스(GameService)가 모든 규칙을 관리하고 있고, Player 객체는 단순한 데이터 저장소 역할만 한다.
이 방식은 비즈니스 로직(심판)이 여기저기 퍼져 유지보수하기 어려워지는 문제가 있다.
감정과 불법이 없는 OOP적 세계라면, 내가 때린거에 대한 내용은 내가 계산하면 된다!
✅ DDD 방식 (객체 중심 설계)
public class Player {
private String name;
private int hp;
private int attackPower;
public void attack(Player defender) {
if (defender.hp <= 0) {
throw new IllegalStateException("이미 죽은 플레이어를 공격할 수 없습니다.");
}
defender.receiveDamage(this.attackPower);
}
private void receiveDamage(int damage) {
this.hp -= damage;
}
}
DDD 방식에서는 Player 객체가 스스로 행동 규칙을 알고 있으며, 서비스 계층이 없어도 게임이 진행될 수 있다.
DDD의 핵심 개념
DDD는 단순한 코드 스타일이 아니라, 몇 가지 중요한 개념이 있다.
🎯 1. 엔티티(Entity)
- 고유한 ID를 가지는 객체
- 상태가 변할 수 있음
- 예: 주문(Order), 사용자(User), 상품(Product)
🎯 2. 값 객체(Value Object)
- ID가 없고, 값 자체가 중요한 객체
- 불변성을 유지해야 함
- 예: Money(화폐 단위), Address(주소)
🎯 3. 애그리게잇(Aggregate)
- 여러 개의 엔티티를 묶어서 하나의 단위로 관리하는 것
- 루트 엔티티를 통해서만 접근 가능
🎯 4. 리포지토리(Repository)
- 애그리게잇을 저장하고 조회하는 역할
- JPA의 @Repository와 유사
부끄러운 기억
기술회의를 갔을 때, 고객사의 개발자분이 "엔티티"라는 용어를 계속 쓰셨다. 잘 이해를 못한 내가 "DB의 테이블을 말하시는 거냐"라고 물어본 적이 있다. 같은 의미이긴 하지만, DDD에 대한 지식이 있었다면 그런 질문을 하지 않았을 것 같다.
당시에는 단순히 테이블과 객체 매핑 정도로만 생각했지만, 지금 와서 보면 DDD에서 말하는 엔티티는 단순한 데이터 저장소가 아니라 비즈니스 로직을 내포하는 핵심 객체라는 것을 이해하지 못한 것 같다.
해당 사업은 새로운 기술을 많이 배우고 익히며 수행한거라 힘들었지만 의미있었다. 갑자기 떠오르네...
DDD와 이벤트 기반 아키텍처
DDD는 이벤트 기반 아키텍처와 자주 함께 사용된다. 예를 들어, 주문이 완료되었을 때 결제 시스템과 배송 시스템이 각각 반응해야 한다고 가정해보자.
public class Order {
private Long id;
private OrderStatus status;
private final ApplicationEventPublisher eventPublisher;
public void completePayment() {
this.status = OrderStatus.PAID;
eventPublisher.publishEvent(new OrderPaidEvent(this.id));
}
}
이렇게 하면 결제 완료 이벤트를 발행하고, 이를 다른 서비스에서 비동기적으로 처리할 수 있다.
정리
- DDD는 비즈니스 로직을 객체에 내재화하는 설계 방식이다.
- 기존의 데이터 중심 설계에서 벗어나, 객체가 스스로 규칙을 알고 행동하는 방식으로 전환한다.
- 핵심 개념으로 엔티티, 값 객체, 애그리게잇, 리포지토리가 있다.
- 이벤트 기반 아키텍처와 함께 활용하면 더욱 효과적이다.
DDD가 모든 상황에서 정답은 아니지만, 복잡한 비즈니스 로직을 관리하는 데 강력한 도구가 될 수 있다. 이직을 준비하면서도 한 번쯤 깊이 고민해볼 만한 개념인 것 같다.
'공부' 카테고리의 다른 글
HTTP, 웹을 움직이는 핵심 프로토콜 (0) | 2025.03.09 |
---|---|
AWS MFA 인증 문제 해결기 (0) | 2025.03.07 |
블로그에 도메인 연결하기 (0) | 2025.03.07 |