Domain Driven Design (DDD)

Avni Ozunlu
5 min readApr 9, 2018

--

Domain Driven Design Nedir?

DDD, geliştirilmiş bir teknoloji veya belirli yöntem değildir. DDD, karmaşık yazılım sistemlerinin geliştirilme aşamasında ve bu karşmaşık projeler hayata geçtikten sonra uygulamalarımızın sürekliliğini sağlamakta sıkça yaşanan temel problemlere çözümler getirmeye çalışan bir yaklaşımdır.

DDD nin babası diyebileceğimiz Eric Evans, Domain Driven Design — Tackling Complexity in the Heart of Software adlı kitabında, yukarıda bahsettiğim karmaşık sistemlerde oluşan problemlerin kaynağının, çoğunlukla domain’ in içinde saklı olduğunu belirtiyor. Bunun da ancak, yaşanılan sorunlarının doğru bir şekilde anlaşılıp, projenin doğru modellenmesi ile gerçekleşebileceğini ortaya koyuyor.

Implementing Domain-Driven Design adlı kitabı ile Vaughn Vernon, Evans’ ın verdiği teorik bilgilerin, gerçekte nasıl kullanıldığını örnek uygulamalar ile anlatmaya çalışmıştır.

DDD yi anlamak için temel bazı kavramlarına hakim olmak gerekiyor. Bu kavramlarla DDD’ ye giriş yapabiliriz.

Ubiquitous Language

Oldukça zor telaffuz edilen bu kavram, DDD’ nin temel taşlarından birini oluşturur. Biz yazılımcıların istenilen çıktıyı üretebilmemiz ve bu çıktının sürekliliğini sağlayabilmemiz için Domain Expert’ ler ile aynı dili konuşacak seviyeye gelmemiz gerekiyor. Sonrasında da edindiğimiz bu tecrübeyi uygulamalarımızı geliştirirken kullandığımız method ve sınıflara expertin kullandığı kavramların isimlerini vererek aktarmamız gerekiyor. Projemizde kullanacağımız her servisin domainde bir karşılığı olması gerekiyor. Böylelikle projede yer alan herkes bu ortak dili konuşabilir birbirini anlayabilir oluyor.

Bounded Context

En başta da belirttiğim gibi DDD komplex sistemlerde kullanılması önerilen bir yaklaşım. Komplex bir domain içerisinde sub domainler içerebilr. DDD’ ye göre de içermelidir. Sıkça verilen bir örnek e-ticaret siteleri ancak güzel bir örnek olduğu için ben de kullanmayı tercih ettim.

Bir e-ticaret sitesi bünyesinde

· Sipariş yönetimi

· Müşteri yönetimi

· Stok yönetimi

· Teslimat yönetimi

· Ödeme Sistemi yönetimi

· Ürün yönetimi

· Kullanıcı yönetimi

gibi bir çok sub domain içerebilir. Bu sub domainlerin gruplandığı gibi, Aggregate Root’ ların (az sonra açıklayacağım) domainde yer alan iş kuralları çerçevesinde mantıksal açıdan birbirleri ile en alakalı olanların biraraya gelerek gruplaştığı ve bu grubun sorumluluklarının net bir şekilde belirlenmiş olduğu yapılar, Bounded Context olarak adlandırılır.

DDD, sistemimizi bu bounded contextlerin birbirleri ile iletişimlerini belli protokoller üzerinden sağlayacak şekilde tasarlamamızı öneriyor. Bu yapıda hiçbir Aggregate Root diğer bir context içindeki entity’ e direk referans almaz sadece o context içindeki Aggregate Root ile iletişim kurabilir.

Entitiy & Value Object

Kendine ait unique bir kimliği olan nesneler Entity olarak adlandırılırken, kendine ait bir kimliği olmayanlar ise value object olarak adlandırılıyor.

Entityler domainimiz içerisindeki bir kavrama denk gelirler. DDD nesne yönelimli programlamaya sımsıkı bağlıdır. İş mantığımızı servislere değil bütünüyle entitylere yığmamızı öneriyor. Kısaca sınıflarımızı, veritabanımızdaki bir tabloya karşılık gelecek şekilde değil, iş mantığımızı oturtacağımız yapıda, bir başka deyişle entitylere logic ekleyerek oluşturmalıyız.

Aggregate Root (AR)

Birbiri ile alakalı entity lerin bir iş kuralını ya da akışını gerçekleştirmek için bir arada kullanılması durumu, Aggregate olarak tanımlanıyor. Kendi başlarına sadece bir nesne olan entityler DDD de iş paylaşımı içerisinde transactional bir bütünlüğe erişerek Aggregate oluştururlar.

Bu yapı içerisinde diğer entity’ lerin koordinasyonunu sağlayacak bir yönetici entity seçilir. Bu seçim aggregate içindeki Aggregate Root u işaret eder. DDD de AR ler direkt ya da dolaylı olarak diğer bir AR deki Entity ile iletişime geçmez ve onların referanslarını içermez. AR ler sadece birbirleri ile iletişim kurmalıdırlar.

Repository

Bir aggregate içerisindeki bütün entity ve value object lerin taşıdığı bilgilerin veri tabanına yazılması amacı ile kullanılan kavramdır. Her bir AR kendisi için oluşturacağımız Repository üzerinden DB işlemlerini transactinal yapıda yine bir bütün olarak gerçekleştirir.

Layered Architecture

DDD nin en temel kavramlarından birtanesi de 4 katmanlı mimarisidir.

· Domain Layer

· Application Layer

· Presentation Layer

· Infrastructure Layer

DDD, yukarıda belirttiğim bu katmanlar üzerinde sistemi kurgulamayı önerirken; domain ve application layerların genelde birbirine karıştırıldığı için yazılımların kompleksleştiğini öğretiliyor.

İşimizle ilgili asıl olan implementasyonu domain katmanda yapmamız gerekirken, bunun use caselerini application katmanında tanımlamalıyız. Bir e-ticaret sitesi düşünelim. Bu web sitesinde kullanıcının her etkileşimi bir use casedir. Bu etkileşim her hangi bir şey eklemesi, silmesi ya da bir stok kontrolü olabilir. Use caselerden bağımsız olarak işin özünü ifade eden iş tanımlarımıza domain katmanında yer veriyoruz. Yazılımcı tabiri ile kodlarımızın core kısmının yer aldığı katman diyebiliriz.

Domain katmanı sistemin temelini oluşturuken domain ile ilgili tüm kavramları burada topluyoruz. En dikkat edilmesi gereken konunun, domain katmanının diğer katmanlara olan bağlılığının minimumda tutulması olduğu belirtiliyor. Özetle; domain katmanında işimizi tanımlıyoruz ve diğer katmanları domaindeki bu işe servis verecek şekilde sistemimizi tasarlıyoruz.

Her sistemin içerisinde e-mail gönderimi gereksinimi doğuyor. Sistemimize email atma ve benzeri işleri yürütecek parçaları eklememiz gerekiyor ama tabi ki domain ve application katmanlarına değil, Infrastructure Layer adı verilen diğer bir katmana.

Kullanıcılar ile etkileşimi sağladığımız katmanızmız da Presentation Katmanı. Bu katmanda sadece kullanıcıya bilgi göstermek ve kullanıcıdan bilgi almak amacı ile oluşturacağımız UI sınıflarımıza yer vermeliyiz.

Domainimizin bütünlüğünü sağlayabilmek adına, ön yüzde (Presentation Katmanı) yapacağımız basit kontrollerin yanı sıra, kötü veri elde etmemize engel olacağını öngördüğümüz gerekli tüm validasyonları, Domain Katmanımızda da sağlamalıyız.

Refactoring

Domain Driven Desing Refactoring kavramını olmazsa olmazlarından biri olarak görüyor. Projemiz geliştirme aşamasındayken ve de canlı ortamlara taşındıktan sonra sürekli olarak devam etmesi gerekir. Aggregate’ lerimizdeki entity’ lere yeni bir özellik eklemek istediğimizde ya da servislerimize yeni bir tanesini ekleyeceğimizde vb. sadece gerekli değişikliği yapıp çıkmamamızı mümkünse ufak bir parça dahi olsa iyileştirmemizi öneriyor.

Clean & Readable Code

Kodumuz içerisinde yapacağımız tüm isimlendirmelerimizi, nesnemizin domaindeki amacının anlaşılmasını sağlayacak şekilde yapmamızı öneriyor. Burada önemli olan, nesnelere verdiğimiz adın ne kadar akılcı kısaltmalardan oluştuğu değil, isimlendirme uzun olsa da yaptığı işi ne kadar iyi anlattığıdır. DDD, bunu başarırsak kodumuzun çok daha okunaklı olacağını belirtiyor. Temiz kod zaten iyi bir yazılımın temel gereksinimleri içerisinde yer alıyor ve bunu sağlamak için biz yazılımcılar belirli araçlar kullanabiliyoruz.

Bu temel kavramlardan sonra DDD nin hangi projelerde kullanılmasının mantıklı olduğu konusunda bilgi vermeye çalışayım. İlk olarak karmaşıklığın yüksek olduğu projelerde fayda sağlayacaktır diyebiliriz. Aksi halde gereksiz iş yükü doğurabilir. En basitinden DDD mantığını öğrenmek ve buna gerçekten uygun kod geliştirmek, yazılımcılar için bile zahmetli ve zordur. Eric Evans ın kitabında bahsettiği DDD yi tam anlamı ile uygulayarak geliştirmeye çalışacağımız projelerin hayata geçiş zamanı, diğer yöntemlere göre oldukça fazladır. Bunun başlıca nedeni iş modelinin bütününde kodlarımızda karşılık bulmayan hiç bir akışın hiç bir kavramın kalmaması için çok sıkı bir çalışma gerçekleştirilmesidir. İşin bütününü ekibe aktarmaları ve yazılım geliştirme süreçlerinin tamamında yer alarak yazılımcılar ile dirsek dirseğe çalışmaları ile nitelendirilen Domain Expert ler yer alır. Bu bile proje sahiplerinin istemeyeceği bir şeydir; çok verimli bir ya da daha fazla uzmanını kaynak olarak uzun bir süre kaybetmesi demektir.

İşte bu uzun süreçte işi, iş süreçlerini ve işin terminolojisini doğru anlamamız için DDD bize yine yardımcı olmaya çalışıyor. Uygulaması eğlenceli olarak anlatılan ve Event Storming adı verilen bu tekniği uygularken ihtiyaç duyacaklarımız, bol bol postit yapıştırabileceğiniz uzun bir duvar, domain expertler, analistler ve pek tabi ki biz yazılımcılar. Event Storming de DDD deki diğer kavramlar gibi başlı başına bir makale konusu olabilir.

DDD de tecrübe kazanmış yazılımcıların, daha önceden başarı ile sonuçlandırdıkları projelerinin yazılım geliştirme aşamasında kazandığı deneyimler vardır. Burada heuristics kavramı ile karşılaşıyoruz ve DDD, yazılımcıların bu heuristics olarak nitelendirdiği öğrenilmiş deneyimlerini birbirleri ile paylaşmasını ve sıradaki projelerinde kullanmalarını tavsiye eder.

Hepimizin bildiği gibi yazılım dünyasında karmaşık problemleri çözmek için kullanılan Design Patterns, tabi ki DDD’ de de kendine yer buluyor.

Domain Driven Design hakkında paylaşacağım bir sonraki yazımda görüşmek dileği ile hepinize ayırdınığınız zaman için teşekkür ederim.

--

--