Back to Blog

Domain Driven Design

February 4, 20263 min
Domain Driven DesignSoftware ModelingBounded Context
Domain Driven Design

Domain Driven Design (DDD)

DDD, yazılımı işin diliyle modelleme yaklaşımıdır. Amaç, kodun business gerçeğini yansıtmasıdır.

Kod şunu anlatmalıdır:

  • Bu sistem ne yapıyor?
  • Neden var?
  • Hangi iş problemini çözüyor?

DDD bir mimari stil değil, bir modelleme yaklaşımıdır. Karmaşıklık yoksa tercih edilmemelidir. Basit CRUD uygulamalarında gereksiz maliyet üretir.

DDD karmaşık domain’leri yönetmek içindir.

Core Kavramlar

1. Ubiquitous Language

Business ve teknik ekip aynı dili konuşmalıdır.

Yanlış:

  • Developer: “User table’a record ekledik.”
  • Business: “Müşteri kayıt oldu.”

Doğru:

Her iki taraf da “Customer Registration” der ve bu ifade kodda da aynen geçer.

Yanlış isimlendirme:

calculateSomething()
handleStuff()
processData()

Doğru isimlendirme:

placeOrder()
cancelSubscription()
calculateInvoiceTotal()

Kod, işin kendisini anlatmalıdır.

2. Bounded Context

Aynı terim farklı bağlamlarda farklı anlamlara gelebilir. Bu nedenle sistem mantıksal sınırlara bölünür.

Örnek:

ContextUser Anlamı
AuthKimlik bilgisi
BillingFatura sahibi
SupportTicket açan kişi

Her context kendi modelini tanımlar. Model paylaşımı yapılmaz.

Bounded context, karmaşıklığı izole etmek içindir.

3. Entity

Kimliği (ID) olan ve zaman içinde değişebilen nesnedir.

Örnek: Customer

  • İsmi değişebilir
  • Email değişebilir
  • Ama ID aynı kalır

Kimlik sabittir, değerler değişebilir.

4. Value Object

Kimliği yoktur. Değeri temsil eder. Immutable’dır.

Örnek:

  • Money
  • Address
  • EmailAddress

50 TL başka bir 50 TL ile aynıdır. Identity yoktur.

Value object’ler eşitliği değer üzerinden belirler.

5. Aggregate ve Aggregate Root

Aggregate, birlikte tutarlı kalması gereken nesne grubudur.

Aggregate Root, dış dünyanın erişebileceği tek entry point’tir.

Order (Aggregate Root)
 ├── OrderItem
 ├── Address

Dış dünya doğrudan OrderItem değiştiremez.

Doğru kullanım:

order.addItem(productId, quantity)

Bu sayede:

  • Invariant korunur
  • Hesaplamalar merkezi yapılır
  • Veri tutarlılığı sağlanır

Repository sadece Aggregate Root için yazılır.

OrderItem için ayrı repository olmaz.

6. Domain Service

Entity’ye ait olmayan ama domain açısından önemli olan iş kurallarıdır.

Örnek:

  • Currency conversion
  • Fraud check
  • Discount calculation

Domain event ile karıştırılmamalıdır.

Domain Event:

  • OrderCompleted
  • PaymentRejected

Event bir olaydır. Domain Service bir davranıştır.

DDD + Clean Architecture

DDD genellikle Clean Architecture ile birlikte uygulanır.

Katmanlar:

  1. Interfaces (Controller / API)
  2. Application Layer
  3. Domain Layer
  4. Infrastructure Layer

Domain Layer

  • Entities
  • Value Objects
  • Domain Services
  • Domain Events
  • Repository interfaces

Domain hiçbir framework bilmez.

Application Layer

  • Use cases
  • Transaction yönetimi
  • DTO dönüşümleri
  • Orchestration

Application iş kuralı barındırmaz.

Infrastructure Layer

  • ORM
  • Database
  • Message broker
  • External APIs

Infrastructure detaydır.

DDD vs Layered

LayeredDDD
Anemic modelRich domain model
Service merkezliDomain merkezli
DB merkezli tasarımDomain merkezli tasarım
Hızlı başlarAnaliz gerektirir

Layered architecture’da business logic genelde service’lerde toplanır.

DDD’de logic entity içinde yaşar.

DDD + Microservices

Her microservice ideal olarak bir bounded context temsil eder.

Kurallar:

  • Ayrı domain
  • Ayrı DB
  • Ortak entity yok
  • Event ile haberleşme

Shared database anti-pattern’dir.

Ne Zaman DDD Kullanılmaz?

  • Basit CRUD sistemlerde
  • Admin panel uygulamalarında
  • Domain karmaşıklığı yoksa
  • Business rule minimumsa

DDD maliyetlidir:

  • Analiz süresi artar
  • Modelleme süresi artar
  • Öğrenme eğrisi yüksektir

Ama karmaşık domain’de büyük avantaj sağlar.