Domain boundary, Modular Monolith’te model, veri sahipliği ve değişiklik sınırını belirler. Yanlış sınır, tek deployment içindeki modülleri birlikte değiştirmeye zorlar. Bu nedenle teknoloji seçiminden önce hangi kuralların ve verinin birlikte değiştiğine bakın.

Deployment modeli operasyonel sınırı, domain modeli ise business anlamını belirler. Bir Bounded Context’in tek bir assembly veya deployable service ile bire bir eşleşmesi zorunlu değildir. Ancak implementasyon modüllerinin bu model sınırını nasıl koruduğunu açıkça tasarlayın.
Core Problem: Yanlış Bölünmüş Domain
Bir sistemi modüllere ayırmak kolaydır. Ancak doğru şekilde ayırmak zordur.
Çoğu ekip şu hatayı yapar:
- Teknik katmanlara göre bölme (Controller, Service, Repository)
- Database tablolarına göre bölme
- UI akışına göre bölme
Teknik katman, tablo veya ekran ayrımı tek başına domain boundary kanıtı değildir. Yine de UI akışı ve veri ilişkileri business capability’leri keşfetmek için ipucu verir. Ayrımı model dili, kurallar ve ownership ile doğrulayın.
Bounded Context: Gerçek Sınır Nerede Başlar?
Domain Driven Design (DDD) içinde Bounded Context, bir modelin geçerli olduğu sınırı ifade eder.
Yani:
Aynı kavram farklı context’lerde farklı anlamlara sahip olabilir.
Örnek:
- Order → satış context’inde sipariş
- Order → warehouse context’inde sevkiyat birimi
Bu kavramların kimliği, davranışı ve kuralları farklıysa tek ortak entity kullanmak iki context’i birbirine bağlar. Ancak aynı kelimenin geçmesi tek başına iki context bulunduğunu kanıtlamaz; domain uzmanlarıyla anlamı netleştirin.
En büyük hata: bu farkı görmezden gelip tek bir “Order” modeli yaratmaktır.
Boundary Belirleme Heuristics (Pratik Kurallar)
Domain boundary bulmak için şu sorular işe yarar:
- Bu modül kendi başına anlamlı mı?
- Hangi operasyon başka modülün sonucuna bağımlı ve bu bağımlılık açık bir contract mı?
- Bu modülün datası başka bir modül için kritik mi?
Sık etkileşim tek başına yanlış boundary değildir. Ancak birlikte değişen kurallar, karşılıklı internal erişim ve döngüsel dependency, sınırı yeniden incelemek için güçlü sinyallerdir.
Domain boundary içinde Aggregate
Bir Bounded Context birden çok Aggregate içerebilir. Aggregate, context veya modül ile aynı sınır değildir; birlikte tutarlı kalması gereken state’i ve invariant’ları korur.
Bir aggregate:
- Consistency boundary’dir
- Transaction tasarımını yönlendirir; fiziksel transaction scope’unu altyapı belirler
- Dış dünyaya tek entry point sunar
En kritik kural:
Dışarıdaki kod, aggregate invariant’larını atlayarak state’i değiştirmemeli. Read-only snapshot veya sorgu modeli sunmak bu kuralı ihlal etmez.
Bu kural ihlal edilirse, modül içi coupling artar ve boundary anlamını kaybeder.
Dependency Rule: Kim Kime Bağımlı?
Boundary tasarımında en önemli konulardan biri dependency yönüdür.
Sağlıklı bir sistemde:
- Domain → business kurallarını framework ve persistence detayından ayırır
- Application → domain’i kullanır
- Infrastructure → en dış katmandır
Ancak modüller arası dependency daha kritiktir:
- Bir modül diğerinin internal yapısını bilmemeli
- Sadece contract üzerinden iletişim kurmalı
Anti-pattern:
Direct repository access (başka modülün verisine doğrudan erişim)
Başka modülün repository veya tablolarına kontrolsüz erişim, model ve schema değişikliklerini iki tarafa yayar. Buna karşılık açıkça sahiplenilen reporting/read contract, gizli repository bağımlılığından farklıdır.
Integration Pattern: Modüller Nasıl Konuşmalı?
Modüller arası iletişim için 3 temel yaklaşım vardır:
1. Direct Method Call
- Basit
- Düşük latency
- Yüksek coupling riski
2. Application Service üzerinden iletişim
- Kontrollü erişim
- Uygun contract ve erişim kuralıyla boundary korunur; service adı tek başına yeterli değildir
3. Domain ve Integration Events
- Doğrudan çağrı dependency’sini azaltır; ancak event schema’sı ve zamanlama üzerinden coupling devam eder
- Event-driven yaklaşım
- Complexity artışı
Domain event, aynı domain içinde in-process çalışabilir; her event broker veya eventual consistency gerektirmez. Modüller arası integration contract’ında ise commit zamanı, delivery, duplicate ve failure politikası ayrıca gerekir. Microsoft’un domain event rehberi bu ayrımı ele alıyor.
Önce basit başla, sadece ihtiyaç olduğunda event-driven modele geç.
En Büyük Hata: Shared Database Illusion
Modular Monolith’te en sık yapılan hata:
“Zaten aynı database, istediğim tabloya erişirim” yaklaşımı
Bu yaklaşım şu sonuçları doğurur:
- Boundary ihlali
- Hidden coupling
- Refactor kabiliyeti kaybı
Doğru yaklaşım:
- Her modül kendi datasının sahibi olmalı
- Başka modülün verisine sahipliği belli bir application/read contract üzerinden erişin; bu contract in-process olabilir
Kırılma Noktası: Boundary Ne Zaman Çöker?
Boundary’ler genellikle şu durumlarda çöker:
- Deadline baskısı altında “shortcut” alınır
- Direct DB access başlar
- Modüller arası dependency kontrol edilmez
Bu ihlaller yaygınlaşıp kalıcı hale gelirse, modüler sınırlar kâğıt üzerinde kalır. Ancak tek bir istisnayı bütün sistemin mimari sınıfını değiştiren bir ölçüt saymayın; erişimleri architecture test ve code review ile takip edin.
Domain boundary ve mimari karar
Modular Monolith’in başarısı teknoloji seçiminden değil, boundary disiplininden gelir.
Eğer domain doğru bölünmemişse, Microservices de çözüm değildir.
Çünkü yanlış bölünmüş bir sistemi dağıtmak, problemi çözmez — sadece daha zor debug edilir hale getirir.
Model sınırı için Bounded Context açıklamasına bakın. Ayrıca Modular Monolith data ownership rehberi, shared database içindeki erişim sınırlarını tamamlıyor
