Domain-Driven Design (DDD) Konseptleri

Abdullah Pazarbaşı
12 min readSep 13, 2023

--

DDD, bir tasarım yaklaşımıdır. Sistematik haliyle bir metodolojidir. Burada, bu metodolojiye dair kavramlardan bahsedildi.

Yüzlerce çember
DDD

Bu makale canlıdır. Zaman içerisinde güncellenebilir.

Mavi Kitap (Blue Book)

Domain-Driven Design’ın ilk kez bir metodoloji olarak anlatıldığı “Domain-Driven Design: Tackling Complexity in the Heart of Software” adlı kitaptır. “Eric Evans” tarafından 2003 yılında telif edilmiştir.

Kırmızı Kitap (Red Book)

Domain-Driven Design’ın uygulamalı olarak anlatıldığı “Implementing Domain-Driven Design” adlı kitap, “Vaughn Vernon” tarafından 2013 yılında telif edilmiştir.

Stratejik Tasarım (Strategic Design) Kavramları

  • Kavramsal Modelleme (Conceptual Modeling)
  • Ortak Dil (Ubiquitous Language)
  • Domain Çeşitleri (Domain Types)
  • Çekirdek Domain (Core Domain)
  • Destekleyici Subdomain (Supporting Subdomain)
  • Damıtma (Distillation)
  • Sınırlandırılmış Bağlam (Bounded Context)
  • Bağlam Haritalaması (Context Mapping)
  • Stratejik Ortaklıklar (Strategic Partnerships)

Kavramsal Modelleme (Conceptual Modeling) Kavramları

  • Alan (Domain)
  • Ortak Dil (Ubiquitous Language)
  • Sınırlandırılmış Bağlam (Bounded Context)
  • Alan Modeli (Domain Model)

Taktiksel Tasarım (Tactical Design) Kavramları

  • Değer Nesnesi (Value Object)
  • Varlık (Entity)
  • Agrega (Aggregate)
  • Agrega Kökü (Aggregate Root — AR)
  • Fabrika (Factory)
  • Hangar (Repository)
  • Alan Hizmeti (Domain Service)
  • Uygulama Hizmeti (Application Service)
  • Alan Olayı (Domain Event)
  • Katmanlı Mimari (Layered Architecture)
DDD konseptleri
Domain’e Dayalı Tasarım Konseptleri

Alan (Domain)

Domain, bir bilgi alanı, etki alanı veya faaliyet alanıdır. Yazılım sisteminin yerine getirmeye çalıştığı iş alanını veya çözmeye çalıştığı problem alanını ifade eder. Domain, belirli bir seviyede uyum (cohesion) kümesidir. Domain içindeki alaka düzeyi kritiktir. Domain içinde yakından alakalılar ile birlikte o kadar da yakından alakalı olmayan şeylerden de bahsedilebiliyorsa, bu vaziyet, bir başka domain veya alt domain’lere (subdomains) işaret eder.

Ortak Dil (Ubiquitous Language)

“Ubiquitous” kelimesinin okunuşuna takıldıysanız, yubikğıdıs benzeri bir okunuşu var :)

İletişimde karmaşıklığı azaltmak, belirsizliği ortadan kaldırmak ve iş gereksinimlerini yazılıma dönüştürme sürecini netleştirmek amacıyla ortak bir dil belirlemek gerekir. İş terimlerinden (business terms) süreç olaylarına (events), iş kurallarından (business rules) sanal iş nesnelerine (business objects), alakalı her kavram için aynı isimlendirmeleri yapmak lazım. Ortak dil belirlemek, sınırlandırılmış bağlam (bounded context) kapsamında şarttır; sınırlandırılmış bağlamlar arası “daha büyük kapsamda” ise mümkün olduğunca benzerlik tavsiye edilir.

  • Günlük iletişimde de
  • gereksinim belgelerinde de
  • yazılım sisteminin kodunda da
  • kullanıcı dokümantasyonunda da

AYNI dil kullanılmalı. Peki bu ortak dili kimler belirler? Sınırlandırılmış bağlam ile alakadar domain uzmanları (domain experts), yazılım geliştiricileri ve tüm stakeholder’lar belirler.

Domain Uzmanı (Domain Expert)

Belirli bir iş domain’inde derin bilgi ve deneyime sahip kişidir. Yazılım takımına iş domain’i hakkında rehberlik etme, iş gereksinimlerini, iş kurallarını ve iş süreçlerini açıklama görevlerini üstlenir. Yazılımın başarılı bir şekilde iş ihtiyaçlarını karşılamasını sağlamak için geliştiriciler ve diğer stakeholder’lar ile yakın çalışır. Ortak dilin oluşmasına katkısı sayesinde doğru iş mantığı ve iş akışlarının yazılıma dönüştürülmesinde kritik bir rol oynar. İhtiyaçları ve beklentileri doğru bir şekilde ifade eder.

Domain Çeşitleri (Domain Types)

Çekirdek Domain (Core Domain)

Domain-driven design yaklaşımı, karmaşık bir sistemi, alt sistemlere bölmeyi (dekompozisyon) salık verir. Bu bir “separation of concerns” misalidir. Bir üst domain alt domain’lerine (subdomains) bölünecekse, önce en kritik, en önemli, olmazsa olmaz meselelere bölünür. İşte bu alamet-i farika (sub)domain’ler, çekirdek (sub)domain’ler (core (sub)domains) olur/olmalıdır. Çekirdek (sub)domain(‘ler) bazen çok açık ve nettir, bazen de çekirdek (sub)domain tespiti için:

  • Temel amaca ulaşma yolunda olmazsa olmazlardan mı?
  • Süreçlerin çoğu bu alanın etrafında mı dönüyor?
  • Orta ve uzun vadede stratejik olarak kritik öneme sahip mi?
  • Bu alanda yapılacak inovasyonlar, iş performansını ateşler mi?
  • Çözümü, benzerlere nispeten rekabet avantajı sağlar mı?
  • Çözümü için özel bir uzmanlık birikimi gerektiriyor mu?

gibi sorular sorulması gerekebilir.

Bazı e-ticaret çekirdek alanları
E-ticaret çekirdek domain’lerinden bazıları

Damıtma (Distillation)

Core (sub)domain’in karmaşıklığını anlamak ve bu karmaşıklığı yalnızca gerekli olan kısımlara indirgemek için yapılır. Dekompozisyon için sorulması gereken sorular bu süreçte sorulur.

Distillation
Damıtma

Damıtma süreci genellikle şu adımları içerir:

  • Core (sub)domain’(ler)in belirlenmesi
  • Core (sub)domain’in subdomain’lerine dekompozisyonu
  • Supporting subdomain’lerin ve generic subdomain’lerin belirlenmesi
  • Core (sub)domain’e has konseptlerin ve bu konseptler arasındaki ilişkilerin modellenmesi
  • Core (sub)domain’leri aşan daha genel kural ve politikaların tanımlanması
  • Subdomain’lere has konseptlerin ve core (sub)domain’ler ile ilişkilerinin modellenmesi
  • Modellerin kod tabanında (codebase) taktiksel tasarımlara dönüştürülmesi

Destekleyici Subdomain (Supporting Subdomain)

Çekirdek (sub)domain’lere nispeten daha az öneme sahip, kritik önemi olmayan, “olmasa da olur ama yarım olur” cinsten, hazır çözümler veya basit tasarımlarla çözüme kavuşturulabilecek meselelerin alanlarıdır. Tek başına kıymetleri yoktur. Bir core (sub)domain ile bir generic subdomain arasında köprü de olabilir.

Genel Subdomain (Generic Subdomain)

Kuruluşa, endüstriye, sektöre has olmayan, hazır çözümler ile çözüme kavuşturulan meselelerin alanlarıdır. Tek başına kıymetlidirler fakat benzersiz olmamaları açısından fark yaratmazlar ve rekabet avantajı sağlamazlar.

Alan Modeli (Domain Model)

Bir yazılım projesinde iş problemine dair çözümün soyut bir temsilidir. Yani domain, yerine getirilmeye çalışılan iş alanı veya çözülmeye çalışılan problem alanı demekse, domain modeli de işte o çözümün kendisidir.

Domain modelinde, iş domain’i ile ilgili tüm bilgiler, ilgili bağlamda, tutarlı ve bütünleşik bir yapıda sunulur. Bu bütünsellik, iş gereksinimlerini anlamayı ve uygulamayı kolaylaştırır.

Domain modeli, yazılımın nasıl tasarlanacağına dair yol gösterir. Gerçek dünya kavramlarını, yazılım nesneleri ve yapılarıyla doğrudan ilişkilendirir. Ve belirlenen ortak dili yansıtır. Günün birinde, iyileştirme veya bakım için tekrar incelendiğinde, domain ile modeli arasında kavramsal ve mantıksal çelişki görülemez (görülememelidir).

DDD, RAD (Rapid Application Development) yaklaşımına terstir.

Sınırlandırılmış Bağlam (Bounded Context)

Sınırlandırılmış bağlam, belirli bir iş bağlamında kullanılan tüm terimler, kavramlar, süreçler ve işlemler için net bir mantıksal sınırdır. Aynı terimlerin ve alanların, farklı bağlamlarda farklı anlamlara gelebileceği durumlar için bir çerçeve sunar.

Bounded context, farklı context’ler arasında net bir ayrım sağlar. Böylece, her biri bağımsız bir şekilde geliştirilebilir. Bu, izolasyon demektir. Tabii ki tamamen izole bir sistem işe yaramaz. O halde böyle bir izolasyon, entegrasyon getirir. Bir bounded context, bir diğeri ile nasıl iletişim kurulacağının tanımlanmasına da imkan verir.

Bir bounded context, bir domain’i kesebilir, ama bir domain modelini kesemez.

Bir domain’i paylaşan farklı bounded context’ler ve bir domain’e ait farklı domain modelleri
Bir domain’in farklı bounded context’ler çerçevesinde farklı modelleri

Domain, mesele ise, domain modeli, çözümdür. Ama bu çözüm, kendi bağlamındaki bir çözümdür.

Domain mesele, domain model çözüm, bounded context çözüm uzayıdır.

Nitekim, bir mesele, farklı bağlamlar çerçevesinde farklı ele alınır, farklı yanları ele alınır, farklı anlam yüklenir. O halde, bir domain, farklı bounded context’ler çerçevesinde farklı modellenecektir. Öyleyse, aynı domain’e ait bu iki modelin bir de birbiriyle etkileşimde olması gerekecektir. İlişki ve etkileşim tarzı da “context mapping” ile tespit edilir.

Bir bounded context, birden fazla runtime environment’ı kapsayabilir fakat bir runtime environment’da birden fazla bounded context barındırılmaması tavsiye edilir.

Bağlam Haritalaması (Context Mapping)

Context mapping, farklı bounded context’ler arasındaki ilişkileri ve etkileşimleri gösteren bir tekniktir. Takımların, farklı bounded context’lerdeki modellerin nasıl bir araya geldiğini anlamalarına ve bu modeller arasında nasıl etkileşimde bulunacaklarını planlamalarına yardımcı olur.

Context mapping süreci, şu adımları içerir:

  • Tüm bounded context’lerin tanımlanması
  • Haritalanacak bounded context’lerin hepsi arasındaki ilişki çeşitlerinin tespit edilmesi
  • İlişkileri belirlenmiş bounded context’lerin etkileşim biçimlerinin modellenmesi
  • Bounded context’lerin, iş hedefleri doğrultusunda stratejik olarak nasıl bir araya geleceklerinin planlanması
  • Plana uygun entegrasyon tekniklerinin seçimi

İkinci adımda sözü geçen ilişki çeşitleri şunlardır:

  • Paylaşılan Çekirdek (Shared Kernel)
  • Ortaklık (Partnership)
  • Boyun Eğen (Conformist)
  • Müşteri —Tedarikçi (Customer — Supplier)
  • Bozulmayı Önleyici Katman (Anti-Corruption Layer)
  • Açık Host Hizmeti (Open-Host Service)
  • Yayımlanmış Dil (Published Language)
  • Ayrı Yollar (Separate Ways)
  • Koca Bir Çamur Topu (Big Ball of Mud)
Context Mapping ve Takımlar Arası İlişki
Context Mapping ve Takımlar Arası İlişki

Paylaşılan Çekirdek (Shared Kernel)

Bir stratejik ortaklık (strategic partnership) yöntemidir. Farklı bounded context’ler arasında ortak olarak kullanılan bir kod tabanını ifade eder. Bu kod tabanı, iki veya daha fazla proje ya da ekip tarafından paylaşılır ve bu projeler veya ekipler, bu ortak çekirdeği değiştirmeden önce birbirleriyle anlaşmalıdırlar.

Paylaşılmış çekirdek genellikle, projeler arasında tekrar eden iş kuralları (business rules), value object’ler, domain event’leri, entity’ler gibi somutlaşmış domain konseptlerini içerir. Bu sayede, kodun yeniden kullanılabilirliği sağlanır ve ekipler arasında daha katı uyum olur. Ancak, bu yöntem iki ekip ya da proje arasındaki bağımlılığı da artırır. Bu nedenle dikkatli bir şekilde yönetilmesi gerekir.

Ya da unutun gitsin. Shared kernel kullanmamak daha iyi. Dağıtık sistemler inşa etmenin kolaylaştığı günümüzde, sırf yeniden kullanılabilir kod (reusable code) elde etmek için, böyle düşük seviye bağımlılıklar pek de mantıklı değil. Hele hele mikroservisler mimarisi benimsenmişse zaten kullanılamaz.

Ortaklık (Partnership)

Bir stratejik ortaklık (strategic partnership) yöntemidir. Partnership ilişkisinde iki sınırlı bağlam birbirine yakın bir şekilde çalışır ve genellikle bir iş hedefi veya işlevsellik sağlama konusunda birlikte sorumludurlar. Bu tür bir ilişki genellikle tarafların birbirine bağımlı olduğu, riskin ve yükün paylaşıldığı senaryolar için uygun olur.

Bu ortaklık türü genellikle ekip üyelerinin sürekli iletişim halinde olmasını ve düzenli olarak bir araya gelmesini gerektirir. Ortak hedeflere ulaşmak için her iki bağlam da kaynaklarını ve çabalarını koordine etmelidir.

Ancak, partnership ilişkisinin riskleri de vardır. Taraflar arasında bir dengesizlik olursa, bu bir bounded context’in diğerini olumsuz etkilemesine yol açabilir.

Partnership ilişkisinde, bir tarafın başarısızlığı genellikle diğer tarafı da etkiler. Bu yüzden sürekli koordinasyon ve iletişim esastır.

Boyun Eğen (Conformist)

Bir stratejik ortaklık (strategic partnership) yöntemidir. Conformist ilişkisinde, bir bounded context’den sorumlu ekip (tüketici taraf), diğer bounded context’den sorumlu ekibin (sağlayıcı taraf) sunduğu modelleri veya API’ı olduğu gibi kabul eder ve ona uyar. Yani, tüketici ekip modelin nasıl oluşturulduğu veya niteliği ile ilgili söz hakkına sahip değildir. Bu durum genellikle sağlayıcı ekibin çok daha büyük veya etkili olduğu durumlar için geçerlidir.

Conformist ilişkisinde, tüketici taraf, sağlayıcı tarafın gelecekte yapacağı değişikliklere ayak uydurmak zorundadır.

Müşteri — Tedarikçi (Customer — Supplier)

Bir stratejik ortaklık (strategic partnership) yöntemidir. Customer — supplier ilişkisinde, bir bounded context’den sorumlu ekip (tüketici taraf), diğer bounded context’den sorumlu ekipten (sağlayıcı taraf) bir hizmet veya yetenek bekler. Ancak tedarikçi taraf, müşteri tarafın ihtiyaçlarını tam olarak karşılamayabilir veya yalnızca belirli bir öncelik seviyesi sağlayabilir. Bu ilişki tarzı genellikle müşteri tarafın, tedarikçi tarafın modellerinin veya hizmetlerinin geliştirilmesi veya iyileştirilmesi konusunda bir söz hakkına sahip olduğu durumlarda tercih edilebilir.

  • Müşteri taraf ve tedarikçi taraf arasında bir kontrat vardır (olmalıdır).
  • Müşteri taraf, tedarikçi tarafa bağımlıdır.
  • Tedarikçi taraf, müşteri tarafın taleplerini önceliklendirebilse de kendi bounded context’ine odaklanmıştır (odaklanmış olmalıdır).

Customer — supplier ilişkisi, iki taraf arasında bir denge gerektirir ve her iki tarafın da aradaki sözleşmeye uygun hareket etmesi beklenir.

Tedarikçi tarafı genellikle müşteri tarafına göre daha az esnektir. Çünkü tedarikçi taraf, genellikle kendi alanında uzmanlaşmıştır ve hal-i hazırda bir ürünü sunmaktadır.

Bozulmayı Önleyici Katman (Anti-Corruption Layer)

Bir stratejik ortaklık (strategic partnership) yöntemidir. Farklı sistemler arasında, bozulmayı önlemeye yarayan izolasyon mekanizması demektir.

  • Bağımlılıkların asgariye indirilmesini (decoupling)
  • Kod taşınabilirliğinin artırılmasını
  • Sistemler arası sözleşmelerin (contracts) daha temiz olmasını

sağlar.

Bu mekanizma, uygulama mimarisi (application architecture) seviyesindeki “mediator” pattern’inin, çözüm mimarisi (solution architecture) veya kuruluş mimarisi (enterprise architecture) seviyesindeki karşılığı olarak düşünülebilir. Bu katman araya girdiğinde ilişkiyi “downstream” ve “upstream” olarak ikiye ayırmış olur.

Tam transparan olmayan, nitelikli bir API gateway’e, anti-corruption layer görevi yüklenebilir.

Anti-corruption layer, şu alt görevleri kapsar:

  • İzolasyon (isolation)
  • Rotalama (routing)
  • Dönüştürme (transformation)
  • Delege etme (delegation)

Açık Host Hizmeti (Open-Host Service)

Bir stratejik ortaklık (strategic partnership) yöntemidir. Open-host service ilişkisinde, bir bounded context (sunucu taraf) diğer bounded context’ler (istemci taraflar) için açık bir arayüz (mesela Web API) sağlar. Bu arayüz genellikle dokümente edilmiştir ve stabildir. Bu, diğer tarafların bu servisi kolaylıkla kullanabilmelerini sağlar. Hizmeti sağlayan bounded context, tüketicilerin ihtiyaçlarını karşılamak için yeterince geniş ve esnektir (olmalıdır).

Bu ilişki tipi, birçok farklı tüketici tarafın bir sağlayıcı tarafa bağımlı olduğu ve servisin çok daha fazla sayıda tüketici tarafından kullanılmasının beklendiği durumlar içindir.

Open-host service ilişki tipi için arayüz versiyonlama olmazsa olmazdır.

Yayımlanmış Dil (Published Language)

Published language ilişki tipi, iki farklı context’in, üzerinden etkileşime girebileceği ortak bir dil veya API oluşturur. Bu, farklı sistemlerin kendi bağlamındaki karmaşık iş mantığını bir kenara bırakıp, yalnızca birbiriyle etkileşime girebileceği bir dil veya model oluşturmasına yardımcı olur. Yani, bu ortak dil yoluyla farklı context’ler birbiriyle “anlaşabilir” ve işbirliği yapabilir.

Bu ilişki tipi genellikle farklı context’ler arasında bir sözleşme oluşturmayı amaçlar. Bu, context’lerin birbirine mümkün olduğunca az bağımlı olmasını sağlar.

Yayımlanan dil, evrensel hale getirilebilir de. Kuruluş içinde kalmak veya müşterilere özel olmak zorunda değil.

Ayrı Yollar (Separate Ways)

Separate ways ilişki, iki bounded context arasında, esasında hiçbir entegrasyon veya etkileşim olmadığını gösterir. Bu durumda, her iki taraf da kendi işlerini birbirinden bağımsız bir şekilde yürütür ve birbirlerinin değişikliklerinden etkilenmez. Diğer bir deyişle, iki bounded context de birbiri için herhangi bir kısıtlama yaratmaz. Bu, genellikle iki bounded context arasında alaka olmadığında veya birbirlerine ihtiyaç duymadıklarında tercih edilir.

Tercih edilen ilişki separate ways ise söz konusu bounded context’lerin birbirine karışmaması ve birbirinden bağımsız evrimleşmesi mümkün olur.

Separate ways, bir “fallback case” olarak düşünülmemelidir. Yani, diğer ilişki tiplerinin tercih edilmediği yerde varsayılan ilişki tipi olarak düşünülemez. El sıkışılıp deklare edilmelidir.

Koca Bir Çamur Topu (Big Ball of Mud)

Big Ball of Mud
Big Ball of Mud

Bir anti-pattern’dir. Big ball of mud, belirgin yapıya, net hiyerarşiye veya düzenli bir tasarıma sahip olmayan yazılım sistemlerini tanımlamak için kullanılır. Sistem zamanla büyüdükçe, “katman” veya “modül” ayrımı olmadığından, çok karmaşık ve bakımı zor bir hale gelir. İşte bu noktada sistem, bir çamur topuna benzer. İç içe geçmiş, çift yönlü akışlara boğulmuş, belki circular dependency’lere dolanmış ve anlaşılması güç bir duruma gelir.

Sistem, koca bir çamur topu ise henüz domain-driven design’ı tam olarak benimseyemezsiniz demektir.

Böyle bir vaziyetin ortaya çıkmasının sebepleri şunlar olabilir:

  1. Yetersiz bounded context tanımı: Muğlak aidiyet, açıkta kalan model, birbirine girmiş modeller doğurur.
  2. Bozuk aggregate tasarımı: Eksik aggregate, eksik entity, entity’nin yanlış aggregate’da bulunması, yanlış aggregate root gibi şeylere sebep olur. Bunlar da yığınla workaround’lara sebep olabilir.
  3. Yetersiz izolasyon ve sınırlandırma: Bir arada olmaması gerekenler bir arada, birbirine bağlı olmaması gerekenler birbirine bağlı, birbiriyle etkileşimde olmaması gerekenler birbiriyle etkileşimde olabilir.
  4. Yetersiz işbirliği veya yetersiz iletişim: Domain expert’lerin yanlış anlaşılması, gereksinimlerin yanlış anlaşılması, netleşmeyen ubiquitous language yanlış modelleme ve yanlış sınırlandırmalara sebep olabilir.
  5. Yüksek teknik borç: Başta kifayetsiz teknik borç olmak üzere her tür teknik borç, DDD benimsensin veya benimsenmesin, sistemi zamanla anlaşılamaz, yönetilemez, güvenilemez, sürdürülemez hale getirir.
DDD Tactical Design
Taktik Tasarım

Değer Nesnesi (Value Object — VO)

Özellikleri olan fakat referans tanımlayıcısı (ID) olmayan, oluşturulduktan sonra değiştirilemeyen (immutable) nesnedir.

Varlık (Entity)

Hem özellikleri olan hem de kolleksiyonu kapsamında benzersiz bir referans tanımlayıcısı (ID) olan nesnedir. Bir entity, yaşam döngüsüne (lifecycle) sahiptir. İçinde bulunduğu aggregate’ın iç tutarlılığı (consistency) korunarak değiştirilebilen (mutable) bir nesnedir. Ancak ID’si değiştirilemez.

Entity, bir DTO (Data Transfer Object) değildir. DDD uygulanmaya çalışılıyorsa, yapılabilecek en büyük hatalardan biri de bir entity’i DTO yerine koymak olur. Bir entity, zengin model anlayışı ile tasarlanmalıdır.

Entity, özellik olarak value object de barındırabilir.

Entity ile DAO (Data Access Object) aynı şey değildir. DDD uygulanmaya çalışılıyorsa, yapılabilecek en büyük hatalardan biri de bunları bir saymaktır. Entity, model merkezli (model-centric) bir yaklaşımın unsurudur. DAO’i entity yerine koymak, veri merkezli (data-centric) yaklaşımı sistem tasarımına sokuşturmaya çalışmak demektir. Ve veritabanı şemasına sıkı sıkıya bağımlılık doğurur.

Agrega (Aggregate)

Tek bir birim gibi ele alınan entity’ler ve/veya value object’ler kümesidir (cluster). Bir domain modelinde bir veya daha fazla aggregate yer alır. Aggregate’ın sınırları içinde bir dizi tutarlılık kuralı sürekli olarak geçerlidir. Yani bir aggregate daima kendi içinde tutarlıdır, ifade gücü yüksektir.

Agrega Kökü (Aggregate Root — AR)

Bir aggregate dışarıdan referans alacaksa, referans yalnızca ve yalnızca o aggregate’ın kök varlığına verilebilir. Buna aggregate root (AR) denir. Yani bir aggregate’ın dışı açısından, o aggregate’ın yalnızca bir ID’si vardır, o da AR’ın ID’sidir. AR, somut olarak bir entity’dir.

Fabrika (Factory)

Belirli bir aggregate’ın benzersiz örneklerini, kendi içinde tutarlı olarak oluşturan tek mercidir. Bir aggregate’ı inşa etmenin ayrıntılarını soyutlar ve kapsüller.

Factory, sorumlu olduğu aggregate pattern’ine ait repository’i kullanamaz.

Hangar (Repository)

Bir veya bir tutam aggregate’ı saklamak için arkaya yollayan veya daha önceden saklanmış bir veya bir tutam aggregate’ı yükleyen (load), kolleksiyon benzeri soyutlama yapan bir arayüze sahip mekanizmadır.

DDD, repository’nin arkası ile ilgilenmez. Dolayısı ile repository’nin nasıl implemente edildiğinin DDD açısından önemi yoktur. DDD açısından önemli olan, repository’nin arayüzü ve oluşturulacak bir aggregate varsa oluşturmak için o aggregate’ın factory’sinin kullanılmasıdır.

Bir repository, ilgili factory’e bağımlıdır.

Alan Hizmeti (Domain Service)

Domain servisleri, domain modeline dahildir. Uygulamadaki bir workflow, ilgili model’e tam karşılık gelmediğinde veya birden fazla aggregate arasında koordinasyon icap ettiğinde, ilave işlevselliklere ihtiyaç var demektir.

Value object’ler ve entity’ler yüklenebileceği tüm davranışsal sorumluluğu yüklenir. Aggregate root’lar ilaveten, aggregate içi koordinasyon için gereken davranışsal sorumluluğu da barındırır. Factory’lerin ve repository’lerin sorumluluklarını da düşersek, aggregate’lar arası koordinasyona ilişkin davranışsal sorumluluklar ve kalan sorumluluklar domain servislerine yüklenir. Yani bir domain modelinin sorumluluk kapsamındaki yetenekler ve davranışlar, son çare, domain servislerinde barınır.

“Anemic aggregate”, DDD için bir anti-pattern’dir. Ve metodolojiyi uygulamada ciddi hatalar yapıldığının göstergesidir.

Uygulama Hizmeti (Application Service)

Domain service’leri, application service’leri ile karıştırılmamalıdır.

Application service’leri, domain hizmetleri ve altyapı hizmetlerini sorumlu olduğu usecase’ler icabı koordine eder.

Alan Olayı (Domain Event)

Bir domain kapsamında meydana gelen bir state değişimini temsil eder. Kuralları veya süreçleri etkileyebilecek değişimi domain dışına yansıtarak bildirmeye yarar. Domain dışına ama bounded context içine yayımlanan event’e domain event denir. Aynı domain içinde kalsa da kalmasa da bounded context dışına yayımlanan event’e integration event de denir.

Sezgisel Yaklaşımlar (Heuristics)

Karmaşık problemleri daha anlaşılır ve yönetilebilir hale getirmek için kullanılan kılavuzlar veya “kısayol” kuralları anlamına gelir. Bunlar, modelleme sürecinde kararlar alırken kullanılabilecek basit ve pratik yönergeler sunar.

Sezgisel yaklaşımlar, bir modelin içeriğini ve organizasyonunu düzenlemek, modelleme sürecini hızlandırmak, ve sorumlu takım üyeleri arasında daha iyi bir uyum sağlamak için kullanılabilir.

Heuristics şunlar gibi aşamalarda kullanılabilir:

  • tasarım kararları
  • modelleme
  • bounded context belirleme
  • context mapping
  • işbirliği ve iletişim
  • risk yönetimi
  • performans iyileştirme
  • kodlama standartları

Katmanlı Mimari (Layered Architecture)

Mavi kitapta anlatıldığı kadarını sundum.

Alan Katmanı (Domain Layer)

Business domain ile ilgili tüm konseptler, logic’ler ve business rule’lar bu katmana dahildir. DDD pattern’lerinin çoğu bu katmanda kullanılır.

Domain layer’ın infrastructure layer’ına bağımlı olmaktan uzak tutulması tavsiye edilir.

Uygulama Katmanı (Application Layer)

Domain servisleri, aggregate’lar, factory’ler ve repository’leri orkestre etmeye yarayan uygulama servislerinin dahil olduğu katmandır.

Altyapı Katmanı (Infrastructure Layer)

Daha somut altyapısal iş ve süreçlerin yer bulduğu daha alt seviye katmandır.

Uygulama Mimarisi Seviyesindeki Daha Yeni Domain-Centric Mimariler

Şunların da ne olduklarına bir göz atılabilir:

  • Hexagonal Architecture / Ports & Adapters Architecture
  • Onion Architecture
  • Clean Architecture

Müellife LinkedIn profili üzerinden ulaşabilirsiniz.

--

--