Domain-Driven Design değişen iş yapış kurallarının,karmaşık yazılım sistemlerinin geliştirme aşaması ve proje hayata geçtikten sonra sürekliliğini sağlamakta kullanılan , sistemlerin artan karmaşıklığına ve yazılım sisteminin desteklediği iş alanlarını anlayarak ve bunlara odaklanarak bu karmaşıklığı yönetme ihtiyacına bir yanıttır.
Eric Evans tarafından ortaya atılmış bir yazılım geliştirme yaklaşımıdır. Kendisi bu yaklaşımın nasıl çalıştığını öğrenmek ve anlamak için bazı kavramlardan bahsediyor:
Bağlam (Context): Bağlam, bir kelimenin veya ifadenin anlamını belirleyen durum ve çevredir. Örneğin, aynı kelime farklı bağlamlarda farklı anlamlar taşıyabilir.
Alan (Domain): Domain, bilgi, etki veya faaliyet alanını ifade eder. Bir iş alanında veya projede geçerli olan konu ve kapsam alanıdır. Her projenin ve işin bir domain’i vardır.
Model (Model): Model, bir alanın seçilmiş yönlerini soyut bir şekilde tanımlayan ve o alandaki sorunları çözmek için kullanılabilen sistematik bir yapıdır. Bu yapı, iş süreçlerini, nesneleri ve ilişkileri kapsar
Domain-Driven Design’nın Temel Prensipleri
Bu prensipler iki ana Stage olarak karşımıza çıkar ;
Stratejik Tasarım (Strategic Design):
- Ubiquitous Language (Her Yerde Geçerli Dil):
- İş ekibi ve yazılım ekibi arasında aynı dilin kullanılmasını vurgular.
- İş terimleri, gereksinimler ve süreçler, yazılım tasarımında ve kodunda da kullanılır.
- Business olarak bulunan kavramların aksiyonların her birinin kod tarafında karşılığı olmasıdır ve bunlardan birinden bahsedildiğinde direkt olarak teknik ekibin kafasında canlanmalı yada teknik ekip bahsettiğinde iş birimi direk anlayabilmelidir.
- Domain katmanı içerisindeki tüm yapılar da (class, entitiy, function, field vb.) bu amaca hizmet eder.
- Örnek: Proje ekibi olarak e-ticaret uygulaması geliştiriyoruz. Müşterileri “Customer” olarak, ürünleri “Product” olarak adlandırıyoruz ve bu terimleri hem iş gereksinimlerinde hem de kod tarafında kullanıyoruz.
2.Bounded Context (Sınırlı Bağlam):
- Domain belirli bağlamlara ayrılır ve her bir bağlam için ayrı bir sınırlı bağlam belirlenir.
- Kompleks bir domain, içerisinde sub domainler içerebilir.
- Bu bağlamlar, iş alanının farklı bölümlerini temsil eder ve her biri kendi içinde tutarlı bir şekilde çalışır.
- Genel olarak Ubiquitous Language’in sürdürülebilirliği ve sub domainin sınır/sorumluluklarının belirlenmesi gibi bir misyona sahiptir.
- Örnek: E-ticaret uygulamamızda “Müşteri Yönetimi” ve “Sipariş Yönetimi” gibi bağlamlar belirlenir. Her bir bağlam, kendi içinde müşterilere ve siparişlere dair tutarlı bilgileri yönetir.
Taktiksel Tasarım (Tactical Design):
- Aggregates/Aggreagete Root(Kümeler):
- Nesnelerin kümeler halinde bir araya gelerek birlikte çalıştığı yapılar oluşturulur.
- Aggregate Root, yani varlık sınıfı, dışarıdan nesne referansları ekleyebilmek için global bir kimliğe sahip olmalıdır.
- Kök dışındaki diğer varlıkların yerel kimlikleri vardır.
- Aggregate sınırları dışındaki hiçbir nesne, kök olmayan nesnelere referans veremez.
- Örnek: Yukarıdaki resimde tamir atölyesi, Arabanın tanımlandığı VIN numarasını kullanıyor. Arabalarda her lastiğin aşınma ve sürüş mesafesi bilgileri kaydediliyor. Lastiğin hangi tekerleğe monte edildiği de kaydedilerek lastiklerin durumu ve değişim zamanı doğru bir şekilde yönetiliyor. Bu sayede, geçmişte hangi lastiğin hangi tekerleğe takıldığını bilerek daha sürdürülebilir bir hizmet veriyor.
2.Entities (Varlıklar):
- İş alanındaki önemli nesneler, varlıklar olarak adlandırılır.
- Nesnenin farklı veya aynı özelliklere sahip olması durumunda bile ayırt edilebilir olması gerekir.
- Bu varlıklar, kendilerine özgü bir kimlikleri vardır ve yaşamları boyunca değişebilirler.
- Örnek: Öğrencilerin aynı öğrenci olarak kabul edilmesi için benzersiz bir kimlik (ID) kullanılır. Kimlik her öğrenciye özel olarak atanır ve veritabanın’da her öğrencinin tekrar kaydedilmesi engellenir. Bu sayede, öğrencilerin aynı öğrenci olup olmadıkları kolayca belirlenir ve öğrencilere yönelik işlemler doğru bir şekilde gerçekleştirilir.
3.Value Objects (Değer Nesneleri):
- Değer nesneleri, sadece değerleri üzerinden tanımlanan nesnelerdir ve kimlikleri yoktur. Eşitlik, değerlerine göre belirlenir.
- Örnek: Adresi bir değer nesnesi olarak düşünebiliriz çünkü sadece sokak, şehir ve posta kodu gibi değerler üzerinden tanımlanır benzersiz bir kimliği yoktur.
4.Repositories/Services (Depolar):
- Veri erişim katmanlarını soyutlamak için Repository tasarım desenini kullanır.
- Services iş kurallarının ve doğrulama işlemleri için kullanılır. Repository bazı kurallar ile birlikte Aggregate-veritabanı iletişimi için kullanılır.
- Örnek: “Müşteri Deposu” ve “Ürün Deposu” oluşturulur. Bu depolar, veritabanına erişimi yönetir ve müşteri ve ürün bilgilerini iş alanı kodundan soyutlar.
Domain-Driven Design aslında Layered Architecture diyebiliriz 4 katmalı mimari DDD’nin en temel kavramlarındandır.
1.Domain Layer (Alan Katmanı):
- Bu katman, domaini temsil eder ve iş süreçlerini, iş mantığını ve varlık (entity) modellerini içerir.
- Temel kavramlar ve iş kuralları bu katmanda tanımlanırız.
- Uygulama bağımsızdır ve diğer katmanlardan bağımsız olarak test edilebiliriz.
2. Application Layer (Uygulama Katmanı):
- Domain katmanını kullanarak uygulama hizmetlerini ve işlemlerini sağlar.
- Domain nesnelerini kullanarak işlemleri yönetir ve uygulama hizmetlerini expose ederiz.
- Kullanıcı isteklerini işlemek ve domain katmanı ile etkileşimde bulunmak için kullanılırız.
3.Infrastructure Layer (Altyapı Katmanı):
- Dış dünya ile olan iletişimi, veritabanı erişimini, ağ iletişimini, dosya işlemlerini ve diğer altyapı işlemlerini sağlarız.
- DDD’de, domain katmanı altyapı katmanından bağımsızdır ve altyapı katmanı, domain katmanını desteklemek için kullanılır.
- Veritabanı bağlantıları, dış servisler ve çeşitli kütüphaneleri içerir.
4.Presentation Layer (Sunum Katmanı):
- Kullanıcı arayüzüyle ilişkilidir ve kullanıcı ile etkileşimi sağlar.
- Web arayüzü, masaüstü uygulaması, API gibi farklı sunum şekilleri bu katmanda yer alır.
- Kullanıcı isteklerini alır ve uygulama katmanına yönlendirir, sonuçları kullanıcıya gösteririz.
Sonuç olarak, Domain-Driven Design, karmaşık domainlerin etkili şekilde ele alınmasını ve kodun iş süreçlerini yansıtacak şekilde tasarlanmasını sağlayarak, yazılım projelerinin başarılı olma yüzdesini artırır. Bu nedenle DDD, uygun senaryolarda kullandığımızda yazılım geliştirme sürecini ve sonuçlarını önemli ölçüde iyileştirebilir.
Bu anlattıklarım temel düzeyde DDD bilgileridir. Başka kaynaklardan da yararlanmanızı tavsiye ederim.