Bir projenin klasörleri şöyle olabilir:

Domain/
Application/
Infrastructure/
Presentation/

Bu yapı tek başına projeyi Domain-Driven Design yapmaz.

Aynı şekilde her modelin yanında Repository interface olması da DDD değildir.

DDD’nin asıl değeri kodu hangi klasöre koyduğumuzdan önce sistemi hangi kavramsal sınırlara böldüğümüzde ortaya çıkar.

Aynı kelime her yerde aynı şeyi ifade etmeyebilir

Bir e-ticaret sisteminde Customer kavramını düşünelim.

Sales açısından customer:

name
segment
campaignEligibility

olabilir.

Billing açısından ise:

billingAddress
taxNumber
creditStatus

önemlidir.

Her iki context’in tek bir devasa Customer modeli paylaşması zamanla modelin bütün domain’lerin ihtiyaçlarını taşımaya başlamasına neden olur.

DDD’nin Bounded Context kavramı burada önem kazanır.

Martin Fowler’ın açıklamasında da Bounded Context, büyük domain modellerinin açık sınırlara ayrılması ve bu modeller arasındaki ilişkilerin bilinçli biçimde tanımlanması olarak ele alınıyor.

Database tablosu domain sınırı değildir

Sık rastlanan tasarım:

OrderService → customer table
PaymentService → customer table
NotificationService → customer table

Kod katmanları güzel görünse bile aslında context boundary yoktur.

Her modül diğerinin datasına doğrudan erişebilmektedir.

Sonuç olarak schema değişikliği bütün sistemi etkiler.

Daha sağlıklı modelde her context kendi bilgisinin sahibi olur.

Payment context’in ihtiyacı yalnızca:

customer_id
billing_reference

ise Customer context’in internal tablosunu okumak yerine gerekli veriyi bir contract veya integration event üzerinden alır.

Cross-context mutation kırmızı bayraktır

Özellikle şu tip kodlar mimari açısından dikkat ister:

PaymentService
   → CustomerRepository
   → OrderRepository
   → InvoiceRepository

Bir application service üç farklı domain’in state’ini kontrolsüz biçimde değiştiriyorsa bounded context sınırları kağıt üzerinde kalmış olabilir.

Bunun yerine:

PaymentCompleted

event’i yayımlanabilir.

Order kendi state’ini değiştirir.

Invoice kendi sürecini başlatır.

Notification kendi mesajını üretir.

Bu yapı otomatik olarak doğru değildir; eventual consistency gibi yeni maliyetleri vardır. Ama domain ownership çok daha nettir.

DDD’nin amacı pattern sayısını artırmak değildir

Aggregate, Value Object, Repository ve Domain Event araçtır.

Hepsini her projede kullanmak zorunda değilsiniz.

Bir CRUD admin ekranının dört katman, üç factory ve altı interface’e ihtiyacı olmayabilir.

DDD’nin başarılı kullanımı kodun ne kadar “enterprise” göründüğüyle ölçülmez.

Model ile gerçek iş alanının birbirine ne kadar iyi uyduğuyla ölçülür.

İyi mimari klasör ağacına baktığınızda değil, değişiklik geldiğinde kendini belli eder.

Bir iş kuralı değiştiğinde sistemin yalnızca ilgili domain alanında değişebilmesi asıl kazanımdır.