asyncfunctionrenderPage(){const data =awaitgetPageDatas();return data;}
Bileşenler hazırlanıyor...
Not içeriği yükleniyor...
// Markdown dosyası okunuyor
// İçerik işleniyor
// Syntax highlighting hazırlanıyor
DDD Genel Bakış | Domain Driven Design Nedir? | Kubilay Bozak
DDD Genel Bakış
2025-06-05
15 min
Domain Driven Design metodolojisinin temel prensipleri, strategic ve tactical patterns. Karmaşık iş problemlerini çözmek için domain odaklı yaklaşım rehberi.
DDD
Domain
Architecture
Design
Strategic Patterns
Yazılım geliştirirken çoğumuzun ilk adımı, veritabanı odaklı bir yaklaşım olur. Özellikle Entity Framework Core (EF Core) gibi araçlarla çalışırken, genellikle veri yapılarımızı ve ilişkileri ön planda tutarız. Ancak, iş kuralları karmaşıklaştıkça ve uygulamalar büyüdükçe, bu yaklaşım bazı sorunlara yol açabilir. İşte tam bu noktada Domain Driven Design (DDD) devreye girer.
DDD'ye Bir Bakış Atalım
DDD, yazılımı geliştirirken odağımızı veriden çok, iş kurallarına ve gerçek hayattaki problemlere yöneltmemizi sağlayan bir yaklaşımdır. Yani, uygulamanın "ne yaptığına" ve "nasıl çalıştığına" odaklanırız. DDD'nin temel amacı, iş birimiyle (domain expert) aynı dili konuşan, esnek ve sürdürülebilir bir kod tabanı oluşturmaktır.
Bu aslında insanların biraz kafasını karıştıran bir durum örnek olarak domain expert dendiği zaman insanların aklına doğrudan çok deneyimli yazılımı yalamış yutmuş bir insan bir geliştirici geliyor şahsen ben ve bir çok arkadaşım böyle düşünmüştük.
Ama aslında konu biraz farklı.
Bir yazılımcıya maden sektörü ile ilgili bir uygulama geliştirmesi söylense, ilgili yazılımcının konuya dair herhangi bir bilgisi olmaksızın uygulama geliştirmesi pek mümkün olmayacaktır. Örnek olarak kardeşim biz bir maden envanteri programı istiyoruz hadi beraber geliştirelim al bu bilgisayar hadi kod yazmaya başla dediğimiz zaman geliştirici eğer veri tabanında ne gibi veriler tutulacak hangi tablo ne ile ilgili bilmez ise hiçbir şey yapamaz değil mi ?
Yazılımcının bu işi gerçekleştirebilmesi için; tutulacak işlenecek yorumlanacak verileri ve yönlendirmeleri , ne şekilde yönlendirileceği, işin mevzuatı vs. gibi türlü bilgilerin aydınlatılması gerekmektedir. Peki bu konulara hakim olan kim var? Sizden projeyi yapmanızı isteyen kişi peki bu kişi yazılım biliyor mu? Hayır . Ama iş akışını ve yürüyüşünü gerekli olan bilgileri bilen bu kişi bizim için domain expert oluyor işte.
Yani daha resmi bir açıklama yapmak gerekirse Domain Expert, yazılımın geliştirilmekte olduğu iş alanının (domain’in) uzmanıdır.
Yani, yazılımcıların kodladığı sistemin gerçek dünyadaki karşılığını çok iyi bilen kişidir.
💼 Kim olabilir?
İş alanına göre farklılık gösterir:
Sektör / Uygulama
Domain Expert
E-ticaret
Pazarlama müdürü, stok yöneticisi
Bankacılık
Kredi analisti, finans danışmanı
Hastane otomasyonu
Doktor, hemşire, hasta kabul görevlisi
Lojistik uygulaması
Nakliye planlayıcısı, depo yöneticisi
İnsan kaynakları yazılımı
İK uzmanı, bordro sorumlusu
🧩 Yazılımdaki Rolü Nedir?
DDD’de Domain Expert’in rolü:
Yazılımcılara iş kurallarını ve süreçleri açıklar
Geliştiricilerle birlikte Ubiquitous Language (Ortak Dil) geliştirir
Gerçek hayat iş akışlarını yazılımla uyumlu hâle getirir
Domain modelin (Entity, Value Object, Aggregate) doğru kurulmasını sağlar
Şimdiye kadar Domain Expert kavramını detaylıca inceledik ve yazılım geliştirirken iş alanına hakim kişilerin ne kadar kritik bir rol oynadığını gördük. Ancak sadece domain expert’in bilgili olması yeterli değil; bu bilgilerin doğru ve eksiksiz bir şekilde yazılıma aktarılması da gerekir.
İşte bu noktada hem yazılımcıların hem de domain expert’lerin aynı dili konuşması büyük önem kazanır. DDD’nin bize sunduğu en güçlü araçlardan biri olan Ubiquitous Language, tam da bu ihtiyacı karşılar.
Ubiquitous Language (Her Yerde Geçerli Ortak Dil)
Domain-Driven Design’ın temel taşlarından biri de “Ubiquitous Language” yani her yerde geçerli ortak dildir. Bu kavram, yazılım geliştirme sürecinde yer alan tüm paydaşların (yazılımcılar, domain expert’ler, ürün sahipleri vb.) aynı dili konuşmasını ifade eder.
Peki neden önemli?
Yazılım geliştirirken yaşanan en büyük problemlerden biri, aynı şeyi farklı şekilde anlatma sorunudur. Örneğin:
Domain uzmanı “müşteri” der, yazılımcı “kullanıcı” olarak kodlar.
Domain uzmanı “ürün tipi” der, yazılımcı “kategori” olarak veritabanına yazar.
Domain uzmanı “sipariş onayı” derken, sistemde bu “durum güncellemesi” olarak geçer.
İşte bu farklar zamanla iletişim kopukluklarına, yanlış modellemelere ve bakımı zor sistemlere yol açar. Ubiquitous Language bu sorunu çözmeyi hedefler.
📌 Ortak Dil Nasıl Oluşturulur?
Yazılımcılar ve domain uzmanları sık sık bir araya gelir.
Kavramlar netleştirilir: “Müşteri” nedir, “Sipariş” nedir, “İptal” ne zaman olur? gibi gibi ...
Bu kavramlar sadece konuşmalarda değil, kodda da birebir kullanılır.
Sınıf isimleri, methodlar, değişkenler, veri tabanı alanları hep bu dile göre yazılır.
bash
public class Order
{ public Customer Customer { get; private set;} public List<OrderItem> Items { get; private set;} public OrderStatus Status { get; private set;}}
Yukarıdaki örnekte “Order”, “Customer”, “OrderItem” gibi kavramlar hem iş dünyasında kullanılan terimlerdir hem de kodun içinde aynen bu şekilde yer alır. Böylece hem yazılımcı, hem domain uzmanı hem de yeni gelen biri sistemi rahatlıkla anlayabilir.
bash
public class Tbl_MainData
{ public string user_info; public string prod_type; public int stt;}
Bu tarz isimlendirmeler, kodun okunabilirliğini ve sürdürülebilirliğini tamamen ortadan kaldırır. İş birimi bu kodu asla okuyamaz, yazılımcı bile birkaç hafta sonra neyi ne için yazdığını unutabilir.
Artık hem domain expert’in kim olduğunu hem de ortak bir dil geliştirmenin neden bu kadar önemli olduğunu öğrendik. Şimdi sırada bu bilgilerin yazılım dünyasında nasıl somutlaştığını anlamak var.
DDD yaklaşımında, tüm iş kurallarının ve süreçlerin odak noktası olan kavram Domain’dir. Yani yazılımın ne yaptığı, nasıl çalıştığı ve hangi problemi çözdüğü sorularının cevabı tam olarak burada saklıdır.
O halde gelin, yazılım geliştirmenin kalbi olan bu “domain” kavramını daha yakından inceleyelim.
🧠 Domain Nedir?
Domain kelime anlamı olarak “alan” demektir. Yazılım geliştirme bağlamında ise domain, uygulamanın çözmeye çalıştığı gerçek dünyadaki iş problemlerinin tamamını ifade eder.
Örneğin:
Bir e-ticaret uygulaması için domain, ürün yönetimi, sipariş işlemleri, müşteri hesapları gibi iş kurallarının tamamıdır.
Bir muhasebe uygulaması için domain, fatura, bütçe, vergi hesaplamaları gibi iş konularıdır.
Domain Ne İşe Yarar?
Teknik detaylardan (veritabanı, API vs.) soyutlanarak iş mantığına odaklanmanı sağlar.
Kodun hem iş birimiyle hem de teknik ekiplerle anlaşılır olmasına yardımcı olur.
Gerçek iş kurallarının yazılımda doğru ve merkezi bir yerde temsil edilmesini sağlar.
Bu konuyu anlamaya çalışırken, daha önce birçok kez EF Core kullanarak uygulama geliştirdiğimden, özellikle Entity kavramı üzerinden düşünmek bana oldukça yardımcı oldu. Çünkü birçok geliştirici gibi ben de projelerime Code-First yaklaşımıyla başlarken, ilk oluşturduğum katman genellikle “Entity” katmanı olurdu.
Bu katman, veritabanındaki tabloları temsil eden sınıfları içerir ve CRUD işlemleri de bu yapılar üzerinden gerçekleştirilir. EF Core ile çalışırken bu yaklaşım oldukça pratiktir; DbContext, DbSet<T> yapılarıyla doğrudan veriye erişebiliriz. Ancak iş karmaşıklaştığında ve uygulama büyüdüğünde, sadece Entity sınıflarına bağlı kalmak bazı sınırlamalara yol açar.
İşte burada Domain kavramı devreye giriyor.
Domain kavramı kendi içerisinde parçalara ayrılıyor Entity + Value Object + Aggregate gibi gibi şimdilik bunu bir bütün olarak düşünüp çok basit örnekler üzerinden konuyu anlatmak istiyorum.
Hemen başlayalım :-)
EF Core Entity sınıfları ile DDD’de geçen Domain Entity’leri ya da Domain kavramı arasındaki fark nedir?
📌 1. Odağı Farklıdır:
EF Core Entity sınıfları genellikle verinin nasıl saklandığı ile ilgilidir. Ama Domain Entity sınıfları, verinin nasıl davrandığı ile ilgilidir.
EF Core Tarzı:
bash
public class Product
{ public int Id { get;set;} public string Name { get;set;} public decimal Price { get;set;}}
Bu sınıfta sadece veriler var. Bu sınıf, bir veritabanı tablosunu temsil eder. Ama bu sınıfa bir iş kuralı (örneğin fiyat güncelleme) eklenmez.
🧠 Domain Model Tarzı:
bash
public class Product
{ public int Id { get; private set;} public string Name { get; private set;} public decimal Price { get; private set;} public Product(int id, string name, decimal price){if(price <0) throw new ArgumentException("Fiyat negatif olamaz."); Id =id; Name = name; Price = price;} public void UpdatePrice(decimal newPrice){if(newPrice <0) throw new ArgumentException("Yeni fiyat negatif olamaz."); Price = newPrice;}}
Burada artık ürün sadece bir veri değil, kendi davranışına da sahip bir varlık (entity) haline geldi. Kurallar sınıfın içinde, dışarı sızmıyor.
2. İçerik Farklıdır:
EF Core Yaklaşımı:
bash
public class Order
{ public int Id { get;set;} public decimal TotalAmount { get;set;} public bool IsPaid { get;set;}}
Burada IsPaid doğrudan dışarıdan set edilebilir.
Herhangi bir iş mantığı yok. public set vardır, doğrudan erişilebilir.EF Core tarafından veritabanına veri okuma/yazma için kullanılır. İçerisinde hiçbir iş kuralı yoktur. Sadece veri taşıma (DTO gibi düşünebilirsin).
Her yerden Price doğrudan değiştirilebilir.
Domain mantığını koruyamazsın. Yarın "fiyat 0'dan küçük olmasın" dediğinde sistemin her yeri kontrol etmen gerekir.
Domain Yaklaşımı:
bash
public class Order
{ public int Id { get; private set;} public decimal TotalAmount { get; private set;} public bool IsPaid { get; private set;} public Order(int id, decimal totalAmount){if(totalAmount <=0) throw new ArgumentException("Tutar sıfırdan büyük olmalı."); Id =id; TotalAmount = totalAmount; IsPaid =false;} public void MakePayment(){if(IsPaid) throw new InvalidOperationException("Bu sipariş zaten ödenmiş."); IsPaid =true;}}
Burada IsPaid dışarıdan doğrudan değiştirilemez. İş kuralları sınıfın içinde uygulanır.
set metotları private ya da hiç yoktur. Dışarıdan erişime kapalıdır.
Değişiklikler methodlarla olur (MakePayment).
Bu sınıf direkt olarak veritabanına bağlı değil, amacı domain davranışı.
Yarın "fiyat 10 Liradan az olamaz" dediklerinde sadece domain üzerinden değişiklik yapman yeterli olur.
3. Anlam Farklıdır:
EF Core Entity’leri veritabanı nesnelerini temsil ederken, Domain Entity’leri gerçek hayattaki nesneleri temsil eder.
Örnek:
bash
public class Order
{ public int Id { get;set;} public decimal TotalAmount { get;set;} public bool IsPaid { get;set;}}
EF Core’daki Order sınıfı sadece bir tablo gibidir.
bash
{ public int Id { get; private set;} public decimal TotalAmount { get; private set;} public bool IsPaid { get; private set;} public Order(int id, decimal totalAmount){if(totalAmount <=0) throw new ArgumentException("Tutar sıfırdan büyük olmalı."); Id =id; TotalAmount = totalAmount; IsPaid =false;} public void MakePayment(){if(IsPaid) throw new InvalidOperationException("Bu sipariş zaten ödenmiş."); IsPaid =true;}}
Ama Domain’deki Order, siparişin ne zaman oluşturulduğu, ödenip ödenmediği, iptal edilip edilmediği, indirime uğrayıp uğramadığı gibi tüm işsel durumları kapsar.
4. Modelin Amacı Farklıdır:
EF Core Entity → Veriyi saklamak için oluşturulur. (Persistence Model)
Domain Entity → İşi anlamak ve çözmek için oluşturulur. (Business Model / Domain Model)
Neden Domain Modeli?
Domain (iş) değişiklikleri hızlı olur, ama veri yapısı daha sabittir.
Domain modelin, database yapısına bağlı olursa esnekliğini kaybedersin.
Test yazarken Domain sınıflarını test etmek kolay olur.
Veritabanını değiştirdiğinde (örneğin Mongo'ya geçince) sadece altyapıyı değiştirirsin, Domain aynı kalır.
Yukarıda gördüğümüz gibi, Domain Model ile EF Core Entity’leri arasındaki en büyük fark, iş kurallarının ve davranışların Domain katmanında toplanmasıdır. Bu sayede gerçek dünyadaki karmaşık iş süreçlerini ve mantıkları kod içinde net ve sürdürülebilir şekilde ifade edebiliriz.
Şimdi Domain karamının genel olarak ne demek olduğunu anladığımızı düşünüyorum.
Artık EFCore Entity kavramını tamamen kafamızdan çıkararak yolumuza devam edelim, yukarıda bahsettiğim gibi Domain kavramı kendi içinde aytılan farklı farklı görevler ve anlamlar üstlenen yapıtaşlarının tümü olarak inceledik. Şimdi artık kavram kavram basit bir şekilde DDD ile ilgili kavramlardan ilerleyelim.
Öğrenmemiz gereken kavramlar sırasıyla.