Domain-Driven Design (DDD) yaklaşımı, karmaşık sistemlerin gerçek iş mantığını kodda yansıtabilmesi için geliştirilmiş bir yazılım tasarım yöntemidir. DDD, sistemin yalnızca teknik altyapısının değil, işletmenin gerçek süreçlerinin ve kurallarının da yazılım mimarisinin merkezine alınmasını sağlar.
Domain-Driven Design (DDD) Nedir?
Domain-Driven Design, yani alan odaklı tasarım, sistem mimarisinin yalnızca teknolojilere veya veritabanına değil, öncelikle iş alanına (domain) göre oluşturulmasını önerir. Amaç, kodun işletmenin kendisi gibi anlaşılır ve tutarlı olmasıdır.
Klasik yazılım geliştirme süreçlerinde önce teknolojiler ve veritabanı tabloları seçilir, ardından iş mantığı kodun çeşitli noktalarına eklenir. Bu da zamanla sistemde karmaşa yaratır. DDD, bu yaklaşımı tersine çevirir ve tasarımın merkezine iş süreçlerinin modellenmesini koyar.
DDD Nasıl Çalışır?
- Öncelikle iş süreçleri detaylı şekilde analiz edilir.
- İşin özü ve kapsamı (domain) belirlenir.
- İş gerçekliğini yansıtan bir model oluşturulur.
- Bu model, kodun temeline yerleştirilir.
Yani kod, sadece sınıf ve fonksiyonlardan değil, gerçek iş kurallarını ve süreçlerini yansıtan canlı bir iş modeli halini alır. Örneğin, DataManager veya HelperService gibi soyut isimler yerine Order, Payment veya Shipment gibi doğrudan iş süreçlerini yansıtan yapılar kullanılır.
DDD ile Klasik Geliştirme Arasındaki Farklar
En büyük fark, odak noktasının teknolojiden işletme mantığına kaymasıdır.
- Klasik geliştirme: Veritabanı ve CRUD işlemleri etrafında döner, iş kuralları kodun farklı yerlerine dağılmıştır.
- DDD: İş kuralları ve süreçleri etrafında döner, kod doğrudan bu gerçekliği yansıtır ve herkes tarafından daha kolay anlaşılır.
Neden DDD Önemlidir?
Büyüyen sistemlerde karmaşıklık katlanarak artar. Eğer kod, iş süreçlerini iyi yansıtmazsa:
- Değişiklikler maliyetli ve riskli olur.
- Daha fazla hata ve bug ortaya çıkar.
- Takım kodu değiştirmekten çekinir, gelişim yavaşlar.
DDD ise:
- Açık bir yapı ve anlaşılır kod sunar.
- Tüm ekip için ortak bir dil oluşturur.
- Kodun tahmin edilebilir ve sürdürülebilir olmasını sağlar.
Karmaşık Sistemlerde Klasik Mimari Neden Çöker?
Başlangıçta sistemler basit görünse de, yeni özellikler, entegrasyonlar ve istisnalar eklendikçe:
- İş mantığı katmanlara yayılır ve tekrarlanır.
- Bazı kurallar kodda, bazıları veritabanında, bazıları ise API katmanında yaşar.
- Sistemin davranışı öngörülemez hale gelir.
İşletmeden Kopukluk
Kod zamanla gerçek süreçleri yansıtmaz ve:
- Abstrakt servisler, sihirli fonksiyonlar artar.
- Bir kuralın nerede uygulandığı belirsizleşir.
- İşletme ve geliştirme farklı dillerde konuşmaya başlar.
Değişiklikte Zorluk
- Bir değişiklik yapmak için birçok farklı noktaya dokunmak gerekir.
- Yeni hatalar ortaya çıkar, geliştirme yavaşlar.
Ekibin ve Kodun Büyümesi
- Birden fazla takım, yeni modüller ve artan yük ile sistemin yönetimi zorlaşır.
- Yapı olmadan kod parçalara ayrılamaz, çakışmalar ve tekrarlar artar.
DDD'nin Temel Prensipleri
Domain-Driven Design'ın başarısının sırrı, büyüyen karmaşıklığa karşı sistemi kontrol altında tutan temel kurallar kullanmasındadır.
Ubiquitous Language (Ortak Dil)
İşletme ve yazılım ekipleri aynı terimleri kullanır. Örneğin, işte Sipariş varsa kodda da Order olmalıdır, Request veya EntityModel gibi karışıklık yaratacak isimler yerine.
Bu ortak dil kodda, belgelerde ve toplantılarda aynen kullanılır, böylece herkes sistemi aynı şekilde anlar.
Alan Modeli (Domain Model)
Sadece veri yapısı değil, gerçek iş kurallarını ve davranışını içeren bir model oluşturulur:
- Nesneler sadece veri tutmaz, davranışları da kapsar.
- Kurallar modelin içinde yer alır, tüm sisteme yayılmaz.
- Örneğin sipariş nesnesi kendi kurallarını bilir: Ödeme yapılabilir mi, iptal edilebilir mi gibi.
Sorumluluğun Ayrılması
- Her parça kendi alanından sorumludur, böylece kaos ve tekrar önlenir.
- İş mantığı controllerlarda veya servislerde dağılmaz, alan modelinde toplanır.
Teknolojiye Değil, Alan Mantığına Odaklanma
- Önce iş mantığı ve model kurulur.
- Daha sonra veritabanı, API ve framework seçimi gelir.
- Böylece teknoloji değişse bile iş modeli sağlam kalır.
Bounded Context: DDD'nin En Güçlü Kavramı
Bounded Context (Sınırlı Bağlam), modelin anlamının net ve tutarlı olduğu sınırları tanımlar. Bir bağlam içinde tüm terimler aynı anlamı taşırken, başka bir bağlamda farklı olabilir.
Örneğin, "Sipariş":
- Ödeme sisteminde bir ödeme işlemi,
- Kargo sisteminde gönderi,
- CRM'de müşteri talebi anlamına gelebilir.
Bütün bunları tek bir modelde birleştirmek kaos yaratır. DDD, sistemi mantıksal olarak bağımsız bağlamlara ayırmayı önerir. Her bağlam kendi modeline, kurallarına ve mantığına sahiptir; doğrudan diğer bağlamlara bağımlı değildir.
Pratik Örnek
Bir e-ticaret sitesinde:
- Ürün kataloğu
- Siparişler
- Ödeme
- Kargo
Her bağlamda "sipariş" farklı bir anlam taşır ve bu normaldir.
Bounded Context'in Faydaları
- Anlam çatışmalarını ortadan kaldırır.
- Sistemi modüler ve ölçeklenebilir kılar.
- Takımların bağımsız çalışmasını sağlar.
DDD Mimarisi: Temel Yapı Taşları
- Entity (Varlık): Kimliğe sahip, zamanla değişebilen nesneler. Örnek: Kullanıcı, Sipariş.
- Value Object (Değer Nesnesi): Kimliği olmayan, sadece değeriyle tanımlanan nesneler. Örnek: Fiyat, Adres.
- Aggregate (Küme): Birbiriyle ilişkili nesneleri yöneten üst nesne (Aggregate Root). Örnek: Sipariş, sipariş kalemleri ile beraber bir aggregat oluşturur.
- Repository (Depo): Veriye erişimi soyutlayan ve domain nesneleriyle çalışan katman.
- Domain Service (Alan Servisi): Birden fazla nesneyle ilgili kuralları barındıran, durumsuz iş mantığı servisleri.
DDD'nin Katmanları ve Mimari Desenleri
- Domain Layer (Alan Katmanı): İş mantığı, varlıklar ve kurallar burada bulunur. Diğer katmanlara bağımlı değildir.
- Application Layer (Uygulama Katmanı): Kullanım senaryolarını yönetir, alan katmanını koordine eder, karmaşık mantık içermez.
- Infrastructure Layer (Altyapı Katmanı): Veritabanı, dış API'ler ve teknik detaylar burada yer alır.
Bu yapı sayesinde iş mantığı teknolojilerden bağımsız olur ve altyapı değişse bile ana model korunur.
Diğer Mimari Desenlerle İlişkisi
DDD sıkça Clean Architecture ve Hexagonal Architecture ile birlikte kullanılır. Temel amaç, iş mantığını merkeze alıp diğer her şeyi onun etrafında kurgulamaktır.
DDD Karmaşık Sistemlerde Nasıl Avantaj Sağlar?
- Sistemi domain, context ve bağımsız modellere ayırır.
- Her parça kendi başına yönetilebilir olur.
- Büyük ekiplerde sorumluluklar netleşir, çakışmalar azalır.
- Mikroservis mimarisi için sağlam bir temel oluşturur.
Daha fazlası için 2025 için Mikroservisler ve Monolitler: Mimari Karşılaştırma yazımızı inceleyebilirsiniz.
DDD'nin Esnekliği ve Değişime Dayanıklılığı
- İşletme değiştikçe, değişiklikler lokal olarak yapılabilir.
- Tüm sistemi etkilemeden yeni özellikler eklenebilir.
- Uzun ömürlü projelerde gelişimi kolaylaştırır.
DDD ve Mikroservislerin İlişkisi
DDD ve mikroservisler sıkça birlikte anılsa da aynı şey değildir. DDD, iş mantığının modellenmesine odaklanır, mikroservisler ise sistemi bağımsız servisler halinde dağıtır.
Her Bounded Context genellikle bir mikroservise karşılık gelir. Böylece servisler arasında anlamlı sınırlar oluşur ve gereksiz bağımlılıklar azalır.
Ancak küçük ve basit projelerde DDD ve mikroservisler gereksiz karmaşıklık getirebilir. DDD'nin avantajı, karmaşık ve uzun ömürlü projelerde daha belirgindir.
Domain-Driven Design'ın Artıları ve Eksileri
Artıları
- Anlaşılır iş mantığı: Kod, işin gerçekliğini doğrudan yansıtır.
- Kolay ölçeklenebilirlik: Bağlamlara göre genişletmek kolaydır.
- Değişime dayanıklılık: Değişiklikler lokalize olur, yan etkiler azalır.
- Takım senkronizasyonu: Ortak dil ve net sınırlar sayesinde iletişim kolaylaşır.
Eksileri
- Zor öğrenim ve uygulama: İş süreçlerini iyi analiz etmek ve deneyim gerekir.
- Yüksek giriş bariyeri: Kavramların ve desenlerin tam anlaşılması zaman alır.
- Küçük projelerde fazlalık: Basit sistemlerde gereksiz karmaşa yaratır.
- İşletme ile yakın işbirliği gerektirir: İş süreçlerinin sürekli anlaşılması ve iletişim gerekir.
DDD Hangi Durumlarda Kullanılmalı?
- Karmaşık iş mantığı olan ve iş kurallarının merkezi olduğu finans, pazar yeri, CRM gibi sistemler.
- Büyük ve uzun ömürlü projeler: Yıllarca gelişen, sürekli değişen uygulamalar.
- Büyük ekipler: Sorumluluğun bölünmesi ve bağımsız çalışma gerektiren projeler.
- Ölçeklenme gereksinimi: Sistem büyüyüp mikroservislere bölündüğünde temel sağlar.
Küçük, basit ve hızlı geliştirilmesi gereken projelerde klasik mimari tercih edilebilir.
Pratik Kural
Eğer sistem "form + veritabanı + az mantık" ise DDD gereksizdir. "Karmaşık süreçler, durumlar ve kurallar" varsa DDD fayda sağlar.
DDD'nin Basit Bir Örneği
- Domain'leri Belirleme: Örneğin bir e-ticaret sitesinde ürün kataloğu, sipariş, ödeme, kargo gibi ana alanlar ayrılır.
- Bağlam İçinde Modelleme: Sipariş bağlamında Order, OrderItem gibi varlıklar ve iş kuralları belirlenir (örneğin, sipariş oluşturulmadan ödeme yapılamaz).
- Davranış Ekleme: Nesneler sadece veri tutmaz, iş mantığını da içerir. Örneğin, createOrder(), pay(), cancel() gibi metotlarla kurallar uygulanır.
- Bağlamları Ayırma: Ödeme bağlamı sadece ödemelerle ilgilenir, teslimat detaylarını bilmez; dağıtım bağlamı ise yalnızca lojistikle ilgilenir.
- Sonuç Yapı: Her bağlam bağımsız model ve logic içerir, sistem mantıksal olarak bölünmüş olur.
Böylece sistem daha anlaşılır, esnek ve hata oranı düşük olur.
Sıkça Sorulan Sorular (FAQ)
DDD nedir, basitçe?
DDD, kodun gerçek iş süreçlerini ve mantığını temel alarak modellenmesini sağlayan bir yazılım geliştirme yaklaşımıdır.
DDD klasik mimariden nasıl ayrılır?
Klasik yaklaşımda veritabanı ve teknik detaylar öndedir, iş mantığı kodun farklı yerlerine dağılır. DDD'de ise önce iş süreçleri ve domain modellenir, kod gerçek süreçleri yansıtır.
DDD her zaman gerekli mi?
Hayır. Küçük, basit veya MVP/prototip projelerde DDD gereksiz karmaşıklık getirir.
DDD mikroservislerle bağlantılı mı?
Doğrudan bağlı değildir, ancak DDD sistemin mantıklı şekilde bölünmesine yardımcı olur ve mikroservis mimarisinin temelini oluşturabilir.
DDD uygulamak zor mu?
Tecrübe ve iş süreçlerinin iyi anlaşılması gerekir, bu yüzden yeni başlayanlar için zordur. Doğru uygulandığında ise büyük fayda sağlar.
Sonuç
Domain-Driven Design yalnızca bir mimari yaklaşım değil, iş süreçlerini yazılımla buluşturan bir düşünce biçimidir. Karmaşık ve uzun vadeli projelerde kodun anlaşılır, esnek ve sürdürülebilir olmasını sağlar. Ancak basit sistemlerde gereksiz yük olabilir. Doğru yerde ve doğru şekilde uygulandığında ise, yazılım geliştirmede gerçek bir fark yaratır.