C#
C# 기초부터 고급까지 Chapter 3.8. Domain-Driven Design(DDD) 도입과 구조 설계
Juan_
2025. 5. 12. 23:11
728x90
📘 Chapter 3.8: Domain-Driven Design(DDD) 도입과 구조 설계
✅ 이 챕터에서 배울 것
- DDD란 무엇인가? 왜 쓰는가?
- 도메인, 유비쿼터스 언어, 애그리거트, 엔티티, 밸류오브젝트
- 계층별 구성 (Domain, Application, Infra, API)
- 실무 프로젝트 예제 구조
- 레이어 간 의존 방향
- 실무에서 마주치는 DDD 오해와 해결 전략
1️⃣ DDD란?
"복잡한 비즈니스 도메인을 객체 모델로 설계하는 방법론"
마틴 파울러의 말:
💬 "도메인 전문가와 개발자가 공통 언어(Ubiquitous Language)를 기반으로 소프트웨어를 만든다."
✅ 왜 쓰는가?
문제 상황 | DDD 도입 효과 |
---|---|
요구사항 변경 잦음 | 유연한 구조로 적응 가능 |
기술 중심 설계 | 비즈니스 중심 설계로 전환 |
코드 구조가 뒤죽박죽 | 도메인 단위로 정리 가능 |
팀 간 소통 안 됨 | 공통 용어 기반으로 일치 |
2️⃣ 핵심 개념 요약
용어 | 설명 |
---|---|
도메인 | 해결하려는 문제 영역 (ex: 주문 시스템) |
유비쿼터스 언어 | 모든 팀원이 공유하는 용어 체계 |
엔티티 | ID를 기준으로 구분되는 객체 (ex: Order) |
밸류 오브젝트 | 값으로만 의미가 있는 객체 (ex: Address) |
애그리거트 | 엔티티 + 관련 밸류 오브젝트 묶음 |
리포지토리 | 객체를 영속화/조회하는 인터페이스 |
서비스 | 도메인의 비즈니스 로직 처리 담당 |
애플리케이션 서비스 | 유스케이스 조율 담당 |
3️⃣ 레이어 구조
/Domain
- Entity, ValueObject, Repository 인터페이스
/Application
- 유스케이스, 서비스, CommandHandler
/Infrastructure
- DB 접근 구현체, 외부 API 연동
/Presentation
- API, UI
✅ 의존성 방향
Presentation → Application → Domain ← Infrastructure
↑
(Ports and Adapters)
💡 Clean Architecture와 DDD는 구조적으로 유사!
4️⃣ 실전 프로젝트 예제: 주문 시스템
📁 Domain Layer
🧱 Order.cs (Entity)
public class Order
{
public Guid Id { get; private set; }
public List<OrderItem> Items { get; private set; } = new();
public void AddItem(Product product, int quantity)
{
Items.Add(new OrderItem(product, quantity));
}
}
🧱 OrderItem.cs (Value Object)
public class OrderItem
{
public Product Product { get; }
public int Quantity { get; }
public OrderItem(Product product, int quantity)
{
Product = product;
Quantity = quantity;
}
}
📁 Application Layer
🧠 OrderService.cs
public class OrderService
{
private readonly IOrderRepository _repo;
public OrderService(IOrderRepository repo)
{
_repo = repo;
}
public void PlaceOrder(Guid userId, List<(Guid, int)> productInfo)
{
var order = new Order();
foreach (var (productId, qty) in productInfo)
{
var product = ProductStore.Get(productId);
order.AddItem(product, qty);
}
_repo.Save(order);
}
}
📁 Infrastructure Layer
public class EfOrderRepository : IOrderRepository
{
private readonly AppDbContext _context;
public EfOrderRepository(AppDbContext context)
{
_context = context;
}
public void Save(Order order)
{
_context.Orders.Add(order);
_context.SaveChanges();
}
}
📁 Presentation (API)
[ApiController]
[Route("api/orders")]
public class OrderController : ControllerBase
{
private readonly OrderService _orderService;
public OrderController(OrderService service)
{
_orderService = service;
}
[HttpPost]
public IActionResult CreateOrder(CreateOrderDto dto)
{
_orderService.PlaceOrder(dto.UserId, dto.Items);
return Ok();
}
}
5️⃣ DDD 흔한 오해
오해 | 진실 |
---|---|
모든 클래스에 DDD 용어 써야 함 | 아니, 비즈니스 중심 영역만 적용 |
Entity/VO 나누는 게 중요 | 중요한 건 유비쿼터스 언어 + 경계 명확화 |
DDD = 복잡함 | 프로젝트에 맞게 경량 도입 가능 |
꼭 Hexagonal이어야 함 | 계층 구조도 OK, 의존 방향만 잘 지키면 됨 |
✅ 정리 요약
항목 | 설명 |
---|---|
DDD란? | 도메인 중심 소프트웨어 설계 방법론 |
핵심 개념 | 엔티티, VO, 애그리거트, 서비스, 리포지토리 |
구조 | Domain → Application → Infra, API |
실무 장점 | 유지보수, 확장성, 팀 협업 극대화 |
도입 팁 | 작게 시작하고 점진적으로 확장하자 |
📢 다음 챕터 예고 🎓
다음 챕터 | 주제 |
---|---|
Chapter 3.9 | CQRS + MediatR 패턴 실전 예제 |
728x90