Vebende Akademi - domain-driven-design
Uzmanla Konuşun
Blog
MAKALE

Domain‑Driven Design (DDD): Karmaşık Yazılım Sistemleri İçin Pratik ve Teorik Rehber

Yayınlayan: Vebende Akademi  |  Okuma süresi: ~60–150 dk

Domain‑Driven Design (DDD): Karmaşık Yazılım Sistemleri İçin Pratik ve Teorik Rehber

Yayınlayan: Vebende Akademi  |  Okuma süresi: ~60–150 dk

1. GİRİŞ

Domain‑Driven Design (DDD), karmaşık iş problemlerini yazılım modellerine doğrudan yansıtmak için Eric Evans tarafından popülerleştirilen bir yaklaşımdır. DDD, teknik tasarım ve iş uzmanlığı arasındaki kopukluğu gidererek sürdürülebilir, anlaşılır ve evrilebilir sistemler inşa etmeyi amaçlar. Özellikle microservices, event‑driven mimariler ve domain‑intensive uygulamalarda DDD'in önemi artmıştır.

Neden bugün önemli?

  • Karmaşık iş kuralları ve çok sayıda paydaş bulunan sistemlerde model doğruluğu sürdürülebilirlik ve bakım maliyetini doğrudan etkiler.
  • Mikroservis ve bounded context odaklı mimariler, DDD prensipleriyle hizalandığında hizmet sınırları netleşir ve bağımsız takımlar daha verimli çalışır.
  • AI, veri‑driven karar süreçleri ve real‑time sistemlerin yaygınlaşması domain uzmanlığı ve net modelleme ihtiyacını büyütmektedir.

Kimler için önemli?

  • Yazılım mimarları ve teknik liderler
  • Backend geliştiriciler ve sistem tasarımcıları
  • Ürün sahipleri, domain uzmanları ve analistler

Hangi problemleri çözüyor?

  • Domain karmaşıklığını yönetilebilir modüllere bölme
  • İş kuralları ile teknolojik kararlar arasındaki uyuşmazlığı azaltma
  • Ekipler arası iletişimi ve model tutarlılığını iyileştirme

2. KAVRAMSAL TEMELLER

2.1 Temel tanımlar

Domain
Problemin çözülmeye çalışıldığı iş alanı veya konu grubu (ör. ödeme, sipariş, envanter).
Model
Domain içindeki varlıkları, ilişkileri ve iş kurallarını temsil eden soyutlama; kod ve terimler aracılığıyla ifade edilir.
Ubiquitous Language
Geliştiriciler ve domain uzmanları arasında paylaşılan ortak dil; tüm kod, test ve tasarım dokümanlarında aynı terimler kullanılır.
Bounded Context
Modelin anlamının tutarlı olduğu sınırlı kapsam. Farklı bounded context'ler aynı terimi farklı anlamlarda kullanabilir; bu sınırlar açıkça tanımlanmalıdır.
Aggregate
Bir işlemle tutarlı kalması gereken bir grup nesne; root entity aracılığıyla dış dünya ile etkileşime girer.
Entity ve Value Object
Entity kimliğe (ID) sahip, yaşam döngüsü olan obje; Value Object kimliksiz, eşitlik ve immutable özellikleri taşır.
Repository
Aggregate'ların saklanması ve getirilmesi için soyutlama katmanı.
Domain Service & Application Service
Domain Service: entity/vo dışında kalan domain davranışı; Application Service: use case orchestration ve transaction boundary yönetimi.

2.2 Stratejik vs Taktiksel DDD

Stratejik DDD, bounded context, context map ve ekip organizasyonu gibi yüksek‑seviye kararlarla ilgilenir. Taktiksel DDD ise aggregate, entity, value object, repository gibi modelleme araçlarını kapsar. Her iki seviyenin birlikte düşünülmesi başarılı DDD uygulamaları için şarttır.

3. NASIL ÇALIŞIR? — TEKNİK MİMARİ VE AKIŞ

3.1 Bounded Context ve Context Map

Büyük bir sistem, mantıksal olarak farklı domain bölümlerine ayrılmalıdır. Her bounded context içinde terimler ve modeller tutarlı olmalıdır. Context Map, bounded context'ler arasındaki ilişkileri (conformist, anti‑corruption layer, shared kernel, partnership) belgeleyen bir haritadır. Örneğin bir e‑ticaret sisteminde "Catalog" ve "Ordering" farklı bağlamlarda farklı iş kurallarına sahip olabilir.

3.2 Ubiquitous Language'in uygulamaya yansıması

Terminoloji kod seviyesinde sınıf, metod ve test isimlerine yansıtılmalıdır. Ubiquitous Language, ekip içi iletişimi basitleştirir ve yanlış anlamaları azaltır. Domain uzmanları ile birlikte terminoloji oturana kadar iteratif workshop'lar yapılmalı ve terimler dokümante edilmelidir.

3.3 Aggregate tasarımı

Aggregate sınırları seçilirken birkaç kural uygulanır:

  • Aggregate, transactional consistency garantisi sağlamak için yeterince küçük olmalı; aşırı geniş aggregate'ler performans ve concurrency problemlere yol açar.
  • Aggregate root tek entry point olmalı; dış dünya aggregate içindeki nesneleri doğrudan değiştirmemeli.
  • İş kuralları aggregate içinde kapsanmalı; yalnızca aggregate'in kendi invariants'ı kontrol etmelidir.

3.4 Persistence ve Repository pattern

Repository, aggregate'ların bulunması ve saklanması için domain seviyesinde soyutlama sağlar. Uygulama katmanı repository ile konuşur, veri tabanı teknolojisi (RDB, NoSQL, event store) repository implementasyonu tarafından soyutlanır. Bu ayrım domain modelinin veri erişim detaylarından korunmasını sağlar.

3.5 Transaction boundary ve eventual consistency

Tek bir aggregate için eşzamanlı transaction mümkünken, farklı bounded context'ler arasında cross‑aggregate transaction maliyetli ve karmaşıktır. Bu yüzden event‑driven asenkron entegrasyon (publish/subscribe, eventual consistency, sagas/compensating transactions) tercih edilir. Saga pattern, uzun süreli iş akışlarını koordine etmek için yaygın bir yaklaşımdır.

3.6 Anti‑Corruption Layer (ACL)

Farklı bounded context'ler arasında bir bağdaştırıcı katmanı (anti‑corruption layer) uygulamak, dışarıdan gelen model ve terimleri iç modelle uyumlu hale getirir. Bu, bir bağlamın diğerinin modelini doğrudan kirletmesini önler ve bağlamlar arasındaki bağımlılığı azaltır.

4. GERÇEK DÜNYA KULLANIMLARI

4.1 Netflix ve domain decomposition

Netflix gibi ölçekli platformlarda domain decomposition (bounded context temelli service boundary'ler) ekiplerin bağımsız çalışmasına olanak tanır. Her ekip kendi bounded context'ini yönetir ve API/contract'lar üzerinden etkileşir. Bu sayede deploy cadence ve domain ownership netleşir.

4.2 Amazon — katalog, sipariş ve fulfillment ayrımı

Büyük e‑ticaret platformlarında katalog yönetimi, sipariş işleme ve fulfillment farklı ekipler ve bounded context'ler olarak ele alınır. Event‑driven entegrasyonlar (order created event → fulfillment) ve anti‑corruption layer'lar ile bağlamlar birbirine bağlanır.

4.3 Finans sektöründe DDD

Bankacılık ve ödeme sistemlerinde domain kuralları kompleks ve regülasyon odaklıdır. DDD, hesap, işlem ve uyumluluk bounded context'lerini açıkça ayırarak audit, risk yönetimi ve kanıtlanabilir süreç akışı sağlar.

4.4 Startup ve ürün odaklı kullanım

Küçük ekipler için DDD'in tüm detaylarını baştan uygulamak aşırı olabilir. Ancak ubiquitous language, açık context boundary ve aggregate düşüncesi ilk iterasyonlardan itibaren büyük fayda sağlar. Mühendislik borcu ve domain karmaşıklığı arttıkça DDD uygulaması kademeli olarak genişletilir.

5. AVANTAJLAR VE SINIRLAMALAR

Avantajlar

  • Domain uzmanlığı ile yazılım modeli arasındaki uyum artar.
  • Ekip sınırları ve servislere dayalı decomposition netleşir.
  • Bakım, test ve evrim süreçleri kolaylaşır: model doğruysa değişimler yerinde yapılır.

Sınırlamalar

  • Öğrenme eğrisi: DDD kavramları ve prensipleri ekip içinde benimsenmelidir.
  • Başlangıç maliyeti: Proje karmaşıklığı düşükse DDD overhead getirebilir.
  • Operasyonel gereksinimler: Event‑driven entegrasyon ve distributed transaction yönetimi ek altyapı gerektirir.

6. ALTERNATİFLER VE KARŞILAŞTIRMA

Yaklaşım Avantaj Dezavantaj
Basit CRUD / monolit Hızlı geliştirme, az başlangıç karmaşıklığı Büyüdükçe bakım zorluğu, model bulanıklığı
Modüler monolit + iyi sınırlar Daha az dağıtık operasyon, net modüller Servis bağımsızlığı sınırlı olabilir
DDD + mikroservis Domain odaklı decomposition, ekip bağımsızlığı Dağıtık koordinasyon, event yönetimi ve operasyonel maliyet

7. EN İYİ PRATİKLER

Production kullanımı

  • Ubiquitous Language'i baştan kurun: terimler kod, test ve dokümantasyonda tutarlı olsun.
  • Bounded Context'leri açıkça tanımlayın ve context map oluşturun.
  • Aggregate sınırlarını iş kurallarına göre belirleyin; küçük tutun ve performans/test gereksinimlerini ölçün.
  • Transactional Outbox ve event bus ile asenkron entegrasyonları güvenilir hale getirin.

Performans ve ölçeklenebilirlik

  • Read ve write store'ları ayrı tutarak okuma yükünü optimize edin (CQRS pattern uygulanabilir).
  • Eventual consistency etkilerini UX ile örtüşecek biçimde tasarlayın; read‑after‑write gerekiyorsa fallback stratejileri sağlayın.
  • Monitoring ve observability: aggregate latency, event publish success, projection lag gibi metrikleri takip edin.

Güvenlik ve veri yönetimi

  • Domain verilerindeki PII'yı minimize edin; event'lerde tokenization veya encryption kullanın.
  • Access control'ü bounded context seviyesinde uygulayın; cross‑context erişimleri ACL veya API gateway ile yönetin.

8. SIK YAPILAN HATALAR

  • Terimlerin ekip içinde farklı anlamlarda kullanılması — Ubiquitous Language yokluğu ciddi teknik borç yaratır.
  • Aggregate'leri aşırı büyütmek — concurrency ve performans sorunlarına neden olur.
  • Bounded context'leri belirsiz bırakmak — servis boundary'leri zamanla çakışır ve entegrasyon karmaşası artar.
  • Eventual consistency'i göz ardı etmek — kullanıcı arayüzü veya iş akışlarında beklenmeyen davranışlar oluşur.

9. GELECEK TRENDLER

  1. Domain‑aware AI araçları: Model önerileri, domain terimlerinin otomatik çıkarımı ve code generation ile DDD pratiği desteklenecek.
  2. Event Mesh ve federated context discovery: Çoklu bulut/multi‑cluster ortamlar için domain‑aware event routing çözümleri yaygınlaşacak.
  3. Serverless & DDD kombinasyonları: Bounded context'lerin hızlı ve maliyet‑etkin olarak bağımsız deploy edilmesi artacak.

EK BÖLÜMLER

Sık Sorulan Sorular (FAQ)

  1. 1. DDD her projeye uygulanmalı mı?

    Hayır. Basit projeler için DDD overhead getirebilir. Ancak domain karmaşıklığı ve takım boyutu arttıkça DDD faydaları öne çıkar.

  2. 2. Ubiquitous Language nasıl oluşturulur?

    Domain uzmanlarıyla workshop'lar düzenleyin, terimleri kod, test ve dokümantasyona yansıtın ve sürekli olarak gözden geçirin.

  3. 3. Aggregate sınırını nasıl belirlerim?

    Transactional consistency, performance ve ownership kriterlerini göz önünde bulundurun. Eğer bir grup entity birlikte tutarlı kalmalıysa aynı aggregate içinde olmalıdır.

  4. 4. DDD ile mikroservis farkı nedir?

    DDD bir modelleme yaklaşımıdır; microservice bir dağıtık mimari stilidir. DDD bounded context'ler mikroservis sınırları için rehberlik eder ancak birebir eşleştirme her zaman gerekli değildir.

  5. 5. Anti‑Corruption Layer ne zaman kullanılmalı?

    Harici sistemler veya farklı bounded context'lerden gelen modeller iç domain'i kirletebiliyorsa ACL katmanı ile çeviri ve adaptasyon yapın.

  6. 6. DDD öğrenme yol haritası nedir?

    Temel DDD kavramlarından başlayın (ubiquitous language, bounded context), ardından taktiksal desenleri (aggregate, VO, repository) uygulayın ve zamanla stratejik DDD pratiklerini (context mapping, team structure) benimseyin.

  7. 7. DDD ile event sourcing birlikte mı kullanılmalı?

    Birbirini tamamlayıcı yaklaşımlardır; event sourcing replay, audit ve timeline avantajı sunar. Ancak işletimsel maliyeti göz önünde bulundurarak karar verin.

  8. 8. DDD uygularken hangi metrikleri izlemeliyim?

    Event throughput, aggregate command latency, projection lag, cross‑context error rate ve domain‑specific SLA metriklerini izleyin.

Anahtar Kavramlar

Bounded Context
Model anlamının tutarlı olduğu sınır; hizmet veya modül seviyesinde düşünülür.
Ubiquitous Language
Domain uzmanı ve geliştirici arasında paylaşılan ortak dil.
Aggregate
Transactional consistency için birlikte ele alınan nesne kümesi.
Anti‑Corruption Layer
Dış modellerin iç modele çevrilmesini sağlayan adaptör katmanı.
Repository
Aggregate'ların erişim ve saklama soyutlaması.

Öğrenme Yol Haritası

  1. 0–1 ay: DDD temelleri, Ubiquitous Language ve bounded context kavramlarını öğrenin; küçük bir domain modelleyin.
  2. 1–3 ay: Taktiksel desenleri (aggregate, VO, repository) uygulayın; test driven development ile domain logic'i doğrulayın.
  3. 3–6 ay: Stratejik DDD: context mapping, team ownership ve anti‑corruption layer uygulamalarını geliştirin.
  4. 6–12 ay: Event‑driven entegrasyon, CQRS/ES kombinasyonları, multi‑team coordination ve governance pratikleri üzerinde deneyim kazanın.