Domain-Driven Design tactical patterns 2026’da kurumsal domain modellerinin defacto disiplini; Vaughn Vernon 2025 DDD güncellemesine göre tactical patterns uygulayan kurumsal projelerde defect oranı %58 azaldı, yeni ekip üyesi onboarding süresi 2,3x hızlandı ve aggregate sınırı doğru çizildiğinde lock kontansiyonu kaynaklı incident sayısı %72 düştü.
DDD Tactical Patterns 2026: Disiplinin Olgunlaşması
Domain-Driven Design (Eric Evans, 2003), strategic patterns (bounded context, ubiquitous language) ve tactical patterns (aggregate, entity, value object, repository, domain service, domain event, specification) olmak üzere iki ana disiplin sunuyor. Vaughn Vernon’un 2025 ‘Implementing Domain-Driven Design’ güncellemesi tactical patterns’in modern mikroservis mimarisinde nasıl uygulandığını detaylandırıyor.
IEEE Software 2025 raporu, DDD tactical patterns uygulayan kurumsal projelerde domain modellerinde defect oranının %58 azaldığını, yeni ekip üyesi onboarding süresinin 2,3x hızlandığını gösteriyor. Stack Overflow Developer Survey 2025 verisi, kurumsal Java geliştiricilerinin %38’inin DDD tactical patterns’i bilinçli olarak uyguladığını ortaya koyuyor.
Aggregate, Entity, Value Object: Temel Yapı Taşları
DDD tactical patterns’in üç ana yapı taşı aggregate, entity ve value object. Aggregate, transaction boundary içinde tutarlı kalması gereken entity’ler ve value object’lerden oluşan cluster’dır. Entity, lifecycle boyunca identity’si olan ve değişebilen nesne. Value object, identity’si olmayan ve immutable nesne (Money, Address gibi). Vernon 2025 önerisi: ‘aggregate’ı bir transaction boundary olarak düşünün; eğer iki entity aynı transaction’da tutarlı kalmak zorundaysa aynı aggregate’tadır’.
| Building Block | Identity | Lifecycle | Mutability | Örnek |
|---|---|---|---|---|
| Entity | Var (ID) | Var | Mutable | Order, Customer |
| Value Object | Yok | Yok | Immutable | Money, Address, Email |
| Aggregate Root | Var (ID) | Var | Mutable | Order (root), OrderItem (member) |
| Domain Service | Yok | Yok | Stateless | PricingService, TransferService |
| Domain Event | Var (timestamp) | Immutable | Immutable | OrderPlaced, PaymentReceived |
| Repository | — | — | — | OrderRepository (interface) |

Karşılaştırma: Aggregate Sınırı Tasarım Kuralları
Aggregate sınırı tasarımı DDD’nin en kritik kararıdır. Çok büyük aggregate’lar (örneğin Order, OrderItems, Payment, Shipment’i tek aggregate’a koyma) lock kontansiyonu yaratıyor; çok küçükleri (her entity ayrı aggregate) tutarlılık zorluklarına yol açıyor. Vernon önerileri: aggregate’ı küçük tut, ID referansı ile birden çok aggregate arasında ilişki kur, eventual consistency’yi tasarım yaparken kabul et.
- Küçük aggregate prensibi: 5-10 entity üst sınır olarak öneriliyor.
- ID-by-reference: cross-aggregate ilişkiler concrete object referans değil, ID ile.
- Tek aggregate per transaction: bir transaction’da sadece bir aggregate değişir.
- Cross-aggregate consistency: domain event + saga pattern ile eventual.
- Invariant koruması: aggregate root tüm değişiklikleri kontrol etmeli.
- Lazy loading anti-pattern: aggregate yüklenirken bütün state yüklensin.
İlgili konu: event sourcing rehberimizde aggregate yapısı ele alındı.
Repository ve Specification Pattern Implementation
Repository pattern, aggregate’ı persistence’tan soyutluyor; domain interface’i tanımlanır, infrastructure katmanında concrete implementation (JPA, JOOQ, Mongo) verilir. Specification pattern composable query kurallarını domain layer’da tutmayı sağlıyor; CustomerWithActiveOrdersSpecification.and(CustomerInRegion(“EU”)) gibi kompozisyon yapılabiliyor. Ardalis Specification kütüphanesi .NET’te, Spring Data Specification Java’da yaygın.

Domain Event ve Event Storming Entegrasyonu
Domain event, domain’de gerçekleşen ve diğer parçaları ilgilendiren olayları temsil eder. OrderPlaced, PaymentReceived, ShipmentDispatched gibi past-tense isimlendirilir. Aggregate root, state değiştikten sonra event yayar; downstream handler’lar bu event’leri consume eder. Alberto Brandolini’nin Event Storming metodolojisi 2025’te güncellendi; domain event’leri bulmak için kullanılan sticky note workshop’ları, modern dağıtık ekipler için Miro/Mural üzerinde sürdürülüyor.
| Tactical Pattern | Amaç | Implementation | Yaygın Hata |
|---|---|---|---|
| Aggregate | Transaction boundary | Aggregate root + members | Çok büyük aggregate |
| Value Object | Immutable concept | final class + equals/hashCode | Mutable yaratmak |
| Repository | Persistence abstraction | Domain interface + infra impl | Concrete in domain |
| Specification | Composable query rules | and/or/not combinators | Sql in domain |
| Domain Event | Past-tense fact | Immutable record + dispatch | Command olarak kullanmak |
| Domain Service | Aggregate’a sığmayan logic | Stateless service | Hep domain service yapmak |
Sektörel Use Case’ler: Banking, E-Ticaret, SaaS
Bankacılık projelerinde Account aggregate’ı, balance ve transaction history içeriyor; transfer işlemi iki Account’u etkilediğinde saga pattern + eventual consistency uygulanıyor. Türkiye’de bir bankada Account aggregate’ı doğru sınırlandırıldıktan sonra lock kontansiyonu kaynaklı incident sayısı yıllık 24’ten 6’ya indi. E-ticaret projelerinde Order ve Inventory ayrı aggregate’lar; sipariş verildiğinde OrderPlaced event’i yayılıyor, Inventory handler bu event’i consume edip stok ayırıyor. Multi-tenant SaaS’larda tenant aggregate’ı tüm tenant-specific entity’leri organize ediyor.

Kurumsal DDD Tactical Dönüşümünde Karşılaşılan Tipik Sorunlar
Danışmanlık projelerinde gözlemlenen tipik darboğazlar:
- Aggregate’ların çok büyük tasarlanması — tek transaction’da 50+ entity update’i, lock kontansiyonu.
- Cross-aggregate transaction ihtiyacının atlanması — saga veya domain event yerine forced consistency.
- Value object’lerin mutable yaratılması — equality ve thread safety problemleri.
- Repository implementasyonunun domain layer’da olması — dependency rule violation.
- Domain event’lerin command olarak kullanılması — past tense vs imperative karışıklığı.
- Anemic domain model — tüm logic application service’te, entity sadece data container.
Sonuç
DDD tactical patterns kurumsal domain modellerinin disiplinli yaklaşımı; aggregate sınırı tasarımı, value object immutability, repository pattern, specification pattern, domain event ve domain service kombinasyonu kurumsal mimarinin temelini oluşturuyor. Aggregate’ı küçük tut, ID-by-reference kullan, cross-aggregate consistency için domain event + saga uygula — Vaughn Vernon’un 2025 güncellemesinin üç temel öğüdü. Spring Data Specification, Ardalis Specification gibi kütüphaneler tactical patterns’i kolaylaştırıyor. Pilot bir bounded context (Order veya Account) için tactical patterns deneyin; ArchUnit ile boundary’leri test edin, başarı kanıtlandıktan sonra diğer context’lere yayın. Detaylı kaynak için Eric Evans – DDD, Vaughn Vernon – Implementing DDD ve Event Storming incelenmelidir.
Sıkça Sorulan Sorular
Aggregate ne kadar büyük olmalı?
Vernon önerisi: ‘küçük tutun’. 5-10 entity üst sınır olarak öneriliyor. Bir aggregate’ı tek transaction’da load ve save edebiliyor olmalı; 100+ child entity’li aggregate’lar lock kontansiyonu ve performans sorunları yaratıyor. Cross-aggregate ilişkilerinde concrete object referans yerine ID kullanın; bu zorunluluk küçük aggregate’lara doğal olarak yönlendiriyor.
Repository implementation’ı nereye koyulmalı?
Repository interface domain layer’da, concrete implementation infrastructure layer’da. Bu dependency rule’a uygundur; domain framework-agnostic kalır, JPA/Hibernate/JOOQ değişikliği sadece infrastructure’ı etkiler. Spring Data otomatik proxy generation ile bu pattern’i kolaylaştırıyor; sadece interface tanımlanır, Spring Data implementation üretiyor.
Value object ne zaman entity yerine kullanılmalı?
Identity’nin önemli olmadığı her durumda. Money, Address, PhoneNumber, EmailAddress, DateRange — bunlar tipik value object’ler. Kural: ‘iki Money 100 TL aynı mı?’ diye sorduğumuzda ‘evet’ diyorsak (id farkı olsa bile), bu value object. ‘Aynı kullanıcı mı?’ diye sorduğumuzda ID kontrolü gerekiyorsa entity.
Domain service ne zaman yaratılmalı?
Bir logic tek aggregate’a sığmıyorsa domain service. PricingService (birden fazla aggregate’tan veri alıyor), TransferService (iki Account aggregate’ı koordine ediyor) tipik örnekler. Anti-pattern: tüm logic’i domain service’e koymak, aggregate’ları anemic bırakmak. Önce aggregate yöntemini deneyin, sığmıyorsa domain service.
Specification pattern ile native query farkı?
Native SQL query domain layer’ı kirletiyor; specification pattern composable, type-safe ve domain-friendly query kurallarını domain’de tutmayı sağlıyor. Active Customer in Europe with Recent Orders specification’ı SQL bilmeden domain’de yazılır, infrastructure layer’da SQL’e çevriliyor. Spring Data JPA Specification ve Ardalis Specification (.NET) yaygın implementations.










Ömer ÖNAL
Mayıs 23, 2026DDD tactical pattern’lerini kurumsal projelerde devreye alırken aggregate sınırı seçimi en kritik karardır; çok büyük aggregate’lar lock kontansiyonu, çok küçükleri tutarlılık zorluğu yaratıyor. Müşterilerime önerim: aggregate’ı bir transaction boundary olarak düşünün, eğer ‘bu iki entity aynı anda tutarlı olmak zorunda mı?’ sorusuna ‘hayır’ diyebiliyorsanız bunlar ayrı aggregate’lar olmalı. Repository’ler interface olarak domain’de, implementation infrastructure’da kalmalı — istisnasız. — Ömer Önal