Ana Sayfa / Blog / Bounded context sınırını çizmenin 4 somut yolu

Bounded context sınırını çizmenin 4 somut yolu

DDD'nin en kafa karıştırıcı kavramı bounded context. 4 farklı açıdan sınırı nasıl çizeceğin.

DDD kitabını okuyan çoğu developer’ın takıldığı ilk yer bounded context. Kavram abstract, Evans’ın örnekleri de eski (kargo şirketi, navy fleet management). Pratikte bu sınırı nasıl çizeceğinizi anlatan çok az kaynak var.

Son 4 yıldır kurduğum SaaS mimarilerinde bounded context sınırlarını çizmek için 4 somut kriter kullanıyorum. Bu yazıda bunları örneklerle göstereceğim.

1. Dil sınırı (linguistic boundary)

Aynı kelimenin farklı departmanlarda farklı anlamı varsa, orada bir bounded context sınırı vardır.

Örnek: e-ticaret sisteminde “Product” kavramı:
– Envanter için: SKU, stock level, warehouse location
– Katalog için: name, description, images, category
– Sipariş için: price at purchase time, quantity, discount
– Kargo için: weight, dimensions, shipping class
– Muhasebe için: cost price, revenue, VAT rate

Her birinin farklı data field’ları ve farklı iş mantığı var. Eğer tek bir Product class’ı kullanırsanız, 50 field’lı bir god object’e dönüşüyor ve hiçbir context için doğru abstraction olamıyor.

Doğru yaklaşım: her context’in kendi Product görünümü olsun. Envanter, katalog, sipariş bağımsız modeller. Context’ler arası veri akışı event veya API ile.

Nasıl test edeceksin: Toplantıda bir kelimeyi herkes aynı şekilde anlıyor mu? Eğer ekipler “Aslında bizim açımızdan Product farklı bir şey” diyorsa, context sınırı oradadır.

2. İşlemsel sınır (transactional boundary)

Bir atomic transaction’da hangi veriler birlikte değişmeli? Bu sorunun cevabı aggregate boundary, ama aggregate’lerin birlikte yaşadığı yer bounded context.

Örnek senaryo: kullanıcı sipariş veriyor. Aynı transaction’da:
– Order kaydı oluşturuluyor (Sipariş context)
– Payment authorize ediliyor (Ödeme context)
– Stock reserve ediliyor (Envanter context)
– Loyalty points hesaplanıyor (Müşteri context)

Bu 4 işlem hepsi aynı transaction’da değil. Order creation synchronous, diğerleri event-driven olabilir. Her biri ayrı bounded context içinde, ve eventually consistent.

Nasıl test edeceksin: “Bu iki tablo her zaman birlikte mi güncellenmeli?” sorusunun cevabı “evet” ise aynı context. Eğer “genelde, ama bazen gecikmeli” ise ayrı context’ler.

3. Takım sınırı (team boundary)

Conway’in yasası: organizasyon yapısı kod yapısını belirliyor. Farklı ekipler farklı sorumluluklar taşıyorsa, kod tabanı da o ayrımı yansıtmalı.

Gerçek bir projede 3 ekibimiz vardı:
– Growth ekibi: kullanıcı kaydı, onboarding, email marketing
– Product ekibi: core feature’lar, dashboard
– Billing ekibi: subscription, invoices, tax

Bu 3 ekip zaten ayrı standup’lara giriyordu, ayrı velocity’leri vardı. Kod tabanını da bu sınırlarla ayırdık. Her ekibin kendi bounded context’i, kendi repo’su, kendi deploy cycle’ı.

Sonuç: ekipler birbirini beklemeden deploy edebiliyor, code review fasit daireden çıkıyor, on-call rotation daha adil oluyor.

Nasıl test edeceksin: “Bu feature’ı kim geliştirir?” sorusunun cevabı net bir tek ekip mi, yoksa “birkaç ekip birlikte mi” diyorsun? İkincisi bounded context problemi.

4. Veri sahipliği (data ownership)

Her bounded context’in kendi veritabanı olmalı mı? İdeal olarak evet, ama pratikte paylaşılan bir DB’de bile veri sahipliğini net çizebilirsin.

Kural: bir tabloyu sadece bir context yazmalı. Diğer context’ler o veriyi read-only olarak görebilir, veya kendi cache’inde bir kopyasını tutabilir.

Örnek: users tablosunu sadece Auth context yazıyor. Order context kullanıcı bilgisi lazım olduğunda ya foreign key ile read yapıyor (monolith’te) ya da event’le kendi database’ine kopyalıyor (microservices’te).

Bu kurala uymazsanız, 2-3 farklı servis aynı tablonun column’larını yazıyorsa, migration değiştirmek korkunç bir iş oluyor. “Bu column’u kim kullanıyor?” sorusunun cevabı 15 dakika alıyor.

Nasıl test edeceksin: Her tablonun yanına “sahip context” etiketi koy. Ondan sonra yazma işlemi yapan her kod tabanı parçasını kontrol et. Sadece sahip context yazıyor mu?

Pratik başlangıç

Yeni bir sistem tasarlıyorsan, şu sırada ilerle:

  1. İş domain’ini event storming workshop’uyla haritalandır. Bütün iş olaylarını post-it’lere yaz.
  2. Aynı dilin konuşulduğu event gruplarını belirle. Bu muhtemel context’lerin.
  3. Her context için “kim sahibi” sorusunu cevapla. Ekip yapısıyla uyumlu mu?
  4. Context’ler arası iletişimi tasarla. Hangi event’ler yayılacak, hangi API’lar expose edilecek?

Bu 4 adım genelde 2-3 gün alıyor ama 2 yıllık geliştirme süresinde aşırı değer katıyor.

Sınırı yanlış çizmenin maliyeti

Bounded context’i yanlış çizmek sonradan düzeltilmesi en pahalı şeylerden biri. Veriler yanlış yerde, ekipler yanlış kod’a dokunuyor, deploy’lar birbirini bekliyor. 3-6 aylık refactor projesine dönüşebiliyor.

Başlangıçta 1-2 gün ekstra düşünmek bu maliyetten kurtarır. Çerçeve: dil, transaction, takım, veri sahipliği, bu 4 perspektiften bakarak karar ver.

Bu konuda bir projeniz mi var?

Kısa bir özet bırakın, 24 saat içinde size dönüş yapayım.

İletişime Geç