“DDD” Üzerine

Ali Can Tahmazoğlu
MoneyPay
Published in
4 min readAug 15, 2023

Domain-Driven Design (DDD), karmaşık yazılım projelerinde etkili bir şekilde çalışmayı ve tasarlamayı amaçlayan bir yaklaşımdır. DDD, yazılımın iş gereksinimlerine odaklanarak daha anlaşılır, bakımı kolay ve genişletilebilir kod tabanları oluşturmayı hedefler.

DDD’nin temel prensipleri şunlardır;

1. İş Alanını Anlama

Öncelikle projenizin iş alanını (domain) ve iş gereksinimlerini derinlemesine anlamaya çalışın. İş uzmanları (domain expert) ve paydaşlarla işbirliği yaparak, iş süreçlerini, terimleri ve gereksinimleri anlamaya odaklanın.

Biz ekibimizde bu süreci yaklaşık 4 haftalık sürede tanımladık. Aynı iş alanı üzerinde çalışan farklı ekiplerden destek aldık. 😉

2. Bounded Contexts Oluşturma

Büyük projeleri daha küçük “bounded contexts” veya sınırlı bağlamlar olarak adlandırılan ayrı parçalara bölmek önemlidir. Her bir sınırlı bağlam, belirli bir iş alanını temsil eder ve kendi içinde mantıksal bir bütünlüğe sahiptir. Bounded contexts’leri tanımlamak, projenizin karmaşıklığını azaltabilir.

Bizim iş alanımız ödeme üzerine olduğundan transaction yönetimi en kritik bağlamdı.

3. Ubiquitous Language (Ortak Dil) Geliştirme

İş uzmanları, geliştiriciler ve diğer paydaşlar arasında anlaşılabilir bir “ubiquitous language” geliştirin. Bu dil, tüm tarafların aynı terimleri ve kavramları kullanmasını sağlar, böylece iletişimdeki anlaşmazlıkları en aza indirir.

Bu konuda ekip içerisinde biz gerçekten aynı dili konuşmadığımızı farkettik. İş analistimizin POS olarak ifade ettiği aslında müşteri (merchant) olduğunu bir süre anlamadan işlerimize devam ettik. Geliştirici ekip bu konudan tamamen bağımsız olarak POS’u terminal olarak düşündü. Bir süre geçtikten sonra farklı şeyler anladığımızı ve kodladığımızı farkettiğimizde ortak dilin ne kadar önemli olduğunu anlamış olduk. 😅

4. Domain Modelini Oluşturma

Her bir bounded context içinde, iş gereksinimlerini ve süreçlerini yansıtan bir domain modeli oluşturun. Bu model, iş süreçlerini, varlıkları (entities) ve değer nesnelerini (value objects) içerir.

Kullanıcılardan bankaya iletilen bilgiler bizim için value object’lerdi. Tabii bunun value object olduğunu anlamak bir süreçti bizim için 🤓

5. Entities ve Value Objects Tanımlama

İş alanındaki varlıkları (entities) ve değer nesnelerini (value objects) tanımlayın. Entities, benzersiz bir kimliğe sahip nesnelerdir (örneğin: bir müşteri). Value objects ise sadece içerikleriyle önemli olan nesnelerdir (örneğin: tarih aralığı).

Ekip olarak biraraya gelerek bunun üstesinden gelmeyi bildik 😌

6. Aggregate Root’ları Tanımlama

Aggregate root’lar, bir veya daha fazla ilişkili varlıklar grubunu yöneten ana varlıklardır. Aggregate root’lar dışındaki varlıklara sadece aggregate root üzerinden erişilmelidir.

Transaction ilk tanımladığımız aggregate root oldu. Neden transaction ? Ödeme sistemlerinin temelini oluşturan transaction bizim için gelen her istekti.

7. Repository Tasarlama

Her bir aggregate root için bir repository tasarlayarak, veri tabanı işlemlerini domain modelinizden izole edebilirsiniz. Repository’ler, aggregate’ları oluşturma, okuma, güncelleme ve silme işlemlerini yönetir.

Bununla birlikte analiz sonuçlarını da içerecek sorguları barındırır.

8. Servisleri Tanımlama

İş süreçlerini ve iş mantığını yürüten servisleri tanımlayın. Servisler, genellikle domain mantığının sınırlarını aşan ve birden fazla aggregate root arasında gerçekleşen işlemleri yönetir.

DDD’nin önerdiği gibi entity’leri domain katmanının dışında izole etmeyi önerdiğinden her bir endpoint’in yaptığı işleri servis katmanında CQRS kullanarak geliştirdik. Binlerce satırlık servis sınıfları bu sayede oluşmamış oldu. 👍

9. UI ve Uygulama Katmanını Tasarlama

Kullanıcı arayüzü (UI) ve uygulama katmanları, domain katmanını saran ve kullanıcı etkileşimini yöneten katmanlardır. Bu katmanlar, domain modelini kullanarak işlem yapar ve sonuçları gösterir.

UI, frontend ve backend takımları biraraya gelerek bu tasarımı gerçekleştirdik. 👌

10. Sürekli İyileştirme

Projenizin ilerleyen aşamalarında, DDD uygulamasını sürekli olarak gözden geçirin ve iyileştirin. İş gereksinimlerini daha iyi yansıtan veya daha basit bir model oluşturmak için değişiklikler yapmaktan çekinmeyin.

DDD’nin uygulanması projeden projeye farklılık gösterebilir. Anahtar, iş gereksinimlerine ve projenin karmaşıklığına uygun bir şekilde DDD prensiplerini adapte etmek ve doğru bir denge kurmaktır. Uygulama sırasında esneklik ve sürekli öğrenme prensiplerine sadık kalmak önemlidir.

Domain-Driven Design (DDD) uygularken yapılan bazı yaygın hatalar şunlardır;

  1. Aşırı Mühendislik

DDD’nin karmaşıklığı, bazen gereksiz derecede karmaşık modeller oluşturulmasına neden olabilir. Bu, projenin gelişimini yavaşlatabilir ve gereksiz zorluklar yaratabilir. Modelleri sade tutmaya ve gereksinimlere odaklanmaya dikkat edin.

2. Yetersiz İşbirliği

İş uzmanları, geliştiriciler ve diğer paydaşlar arasındaki iletişim eksikliği, modelin gerçek iş gereksinimlerini yansıtmamasına yol açabilir. Sürekli işbirliği ve iletişim önemlidir.

3. Teknik Odaklılık

DDD, öncelikle iş gereksinimlerine odaklanmalıdır. Ancak bazen geliştiriciler teknik detaylara daha fazla odaklanabilir ve iş gereksinimlerini göz ardı edebilir. Teknik çözümler, işin ihtiyaçlarına uygun olmalıdır.

4. Kapsamlı Modellerin Oluşturulması

Her şeyi tek bir kapsamlı model içinde sıkıştırmaya çalışmak, modelin karmaşıklığını artırabilir. Bu, genellikle sınırlı bağlamların oluşturulmasını ve modellerin küçük ve anlaşılır parçalara bölünmesini engeller.

5. Aggregates ve Aggregate Root’ların Yanlış Anlaşılması

Aggregate root’ları yanlış belirlemek veya yanlış anlamak, modelin bütünlüğünü zedeler. Her aggregate birbiriyle ilgili nesneleri gruplandırmalı ve root dışarıdan erişilebilen bir nokta olmalıdır.

6. Veri Tabanı Tasarımını Modelle Karıştırma

Veri tabanı tasarımı, domain modelden ayrılmalıdır. DDD, iş gereksinimlerine odaklandığı için, veri tabanı tasarımını bu gereksinimlere uyarlamak daha iyidir.

7. Ortak Dil Eksikliği

Tüm paydaşlar arasında kullanılan ortak bir dil oluşturulmazsa, iletişim sorunları ve anlam karmaşası yaşanabilir.

8. Testlerin İhmal Edilmesi

DDD modelinizin işlediğinden emin olmak için yeterli sayıda ve çeşitlilikte testler oluşturulması önemlidir.

9. Sadece Teknolojiyi Kullanma

DDD, sadece bir teknoloji veya araç değil, bir yaklaşımdır. Teknoloji yerine iş gereksinimlerine odaklanmak önemlidir.

Son olarak; DDD’nin anlaşılması ve uygulanması bazen zor olabilir, ancak bu hatalardan kaçınarak ve sürekli olarak paydaşlarla işbirliği yaparak, projenizin daha etkili ve anlaşılır bir şekilde ilerlemesini sağlayabilirsiniz.

--

--