Yazılım Mimarileri ve Tasarım Desenleri Üzerine

Loosely Coupled Sistemler Oluşturmak İçin Domain Event’ler Nasıl Kullanılır?

Merhaba,

Bu yazımızda, günümüzde birçok modern yazılım tasarımı ve mimarisi tarafından tercih edilmekte olan Domain Event‘ler eşliğinde loosely coupled(gevşek bağlı) sistemler oluşturma yaklaşımı üzerine biraz hasbihalde bulunalım istiyorum. Bu süreçte domain event’ler ile integration event’lerden bahsedecek ve ikisi arasındaki temel farkların neler olduğunu değerlendirecek ve biryandan da domain event’lerin nasıl uygulandığına ve özellikle EF Core gibi bir framework ile nasıl işlendiğine ve MediatR gibi kütüphaneyle de nasıl handle edildiğine pratiksel olarak değiniyor olacağız. O halde buyrun başlayalım…

Bir yazılım sisteminde birbirinden farklı bileşenler/servisler/yapılar birbirlerine ne kadar sıkı bağımlı ise o sistemde ihtiyaç dahilinde olan değişikliklere karşın olası dirençlerin bir o kadar yüksek ihtimal olduğunu söyleyebiliriz. Bu mantıkla bu bileşenleri mümkün mertebe loosely coupling(gevşek bağlı) olacak şekilde tasarlarsak eğer sistemdeki herhangi bir değişiklik durumunda diğer kısımlar büyük sorunlara yol açmayacak, bahsi konu olan değişikliğe karşı direnç oldukça zayıf olacaktır.

İşte, bizler birbirleriyle gevşek bağlı bileşenler oluşturmak istiyorsak eğer Domain-Driven Design(DDD) felsefesinin taktiksel bir deseni olan domain event’lerden istifade edebiliriz.

Domain event’ler sayesinde sistem bileşenleri arasındaki sıkı bağlantıları gevşetebilir ve böylece bir bileşende meydana gelen/gelecek olan değişim(ler) neticesinde diğer bileşenlerin doğrudan etkilenmesinin büyük ölçüde önüne geçebiliriz. Böylece var olan özellikleri modifiye etmenin dışında, sisteme yeni özellikleri ekleme sürecinde de esneklikler kazandırılabilmetkedir.

Bileşenler arasındaki gevşek bağlılığın bir diğer getirisi, bileşenlerin daha iyi bir şekilde modüler olmasını ve böylece bir bileşenin, diğer bileşenlerin nasıl tepki vereceklerine dair bilgi edinmek zorunda olmama gibi bir özgürlüğe sahip olmasını sağlamaktadır. Bu durum da sistemdeki bağımsızlık düzeyini arttıracak ve özellikle dağıtık modülerliğe uygun bir nitelik arz edecektir.

Tüm bunların dışında domain event’ler, olayların gönderildiği anda işlenebileceği gibi hedef bileşenin iş yoğunluğuna yahut durumuna uygun olacak şekilde de belirli bir zamanlamada ele alınabilmekte ve böylece zamanlama ve uygulama bağımsızlığı açısından uyum sağlayabilmektedirler.

Şimdi gelin tüm bu altını çizdiğimiz prensipleri uygulamada gerçekleştirebilmemizi sağlayan domain event’lerin tam teferruatlı bir tanımını gerçekleştirerek içeriğimizin seyrine devam edelim.

Domain Events Nedir?

Domain Event, bir yazılım sisteminde gerçekleşen önemli olayları temsil eden ve diğer bileşenlerle iletişimi sağlayan bir kavramdır. Yukarıdaki satırlarda da bahsedildiği gibi Domain-Driven Design(DDD) yaklaşımının bir parçasıdır ve mimaride loosely coupling’i teşvik etmek için kullanılır.

Domain event’i, sistemdeki önemli bir işlemin gerçekleşmesi neticesinde, etki(fact) olarak nitelendirebileceğimiz anahtar noktalar olarak düşünebiliriz. Misal olarak; bir e-ticaret uygulamasında bir siparişin tamamlanması neticesinde ‘OrderCompleted’ gibi bir domain event oluşturulabilir ve böylece bu event sayesinde sistemin farklı katmanlarına siparişin tamamlandığına dair bilgi göndererek iletişim sağlanabilir. Tabi bu iletişimin kurulabilmesi ve diğer bileşenler tarafından gerçekleşen olaya karşılık uygun tepkinin verilebilmesi için yayınlanmış olan domain event’e diğer bileşenler tarafından abone olunması gerekmektedir.

Domain event’ler, ayrıca sistemde asenkron işlemleri destelemek için de kullanılabilmektedirler. Buna da bir örnek vermemiz gerekirse eğer; sipariş tamamlandıktan sonra arka planda müşteriye bir teşekkür maili göndermek isteyebiliriz. Bunun için asenkron bir tutum sergilememizi sağlayan domain event’lerden yine istifade edebiliriz.

Bir olay/event, geçmişte olmuş bir şeyi/olayı ifade eder. O yüzden domain event’lere sürekli geçmiş bir isim verilmelidir!

Integration Events Nedir?

Integration event ise distributed sistemlerdeki farklı bileşenlerin ve hizmetlerin iletişimini kolaylaştırmak için kullanılan bir kavramdır. Genellikle microservice mimarisinde, servisler arası etkileşimi ve iletişimi kurgulamak için kullanılmaktadırlar. Yani integration event için domain event’in dağıtık mimarideki muadilidir diyebiliriz.

Integration event’lerin temel özellikleri şunlardır;

Domain Event ile Integration Event Arasındaki Farklar Nelerdir?

Domain event ile integration event anlamsal olarak birebir aynıyken, amaçsal olarak ise tamamen farklı vizyonlara sahip kavramlardır.

Evet, anlamsal olarak aynıdırlar… Çünkü, her ikisi de geçmişte meydana gelen bir olayı temsil etmektedirler ve biryandan da olay tabanlı iletişim yaklaşımının bir ürünüdürler.

Amaçsal açıdan ise farklılık arz ederler. Domain event’ler; bir yazılım sisteminin içindeki bileşenler arasındaki iletişimi kolaylaştırmak için kullanılırken, integration event’ler ise farklı sistemler veya servisler arasındaki iletişimi kolaylaştırmak için kullanılırlar. Yani domain event’ler aynı yazılım sistemi içerisindeki bileşenler arasında in-memory üzerinden senkron veya asenkron işlev görürken, integration event’ler ise genellikle farklı sistemler arasında message broker’lar vasıtasıyla asenkron varlık gösterirler.

Ayrıca domain event’ler, genelikle bir bileşen tarafından üretilir ve yayınlanır. Diğer bileşenler ise bu olaylara abone olarak, dinleme işlevini yürütürler. Integration event’ler ise daha geniş bir ortamda iletişimi sağladığından, genellikle bir message broker aracılığıyla yönetilir. Bir servis tarafından olay yayınlandığında, bu message broker’a gönderilir ve diğer bileşenler bu olayları oradan takip ederek bütünsel işlevsellik ve iletişim sağlanmış olur.

Domain Events Nasıl Oluşturulur ve Uygulanır?

Şimdi içeriğimizi esas konu olan domain event’lere odaklı bir şekilde seyretmeye devam edelim ve domain event’leri tasarlama detaylarından bahsederken biryandan da nasıl uygulanabileceğini pratiksel olarak inceleyelim.

.NET’te domain event’leri uygulamak için şuana kadar aklıma gelen aşağıdaki dört farklı yöntemden istifade edebiliriz;

Peki hoca! Domain event’ler nerede tetiklenmelidirler? şeklinde sorunuzu duyar gibiyim… Bu haklı soruyu hemen cevaplandırmaya çalışırsak eğer, domain event’ler genellikle domain modelinde gerçekleşen kimi önemli olaylar üzerinde tetiklenirler diyebiliriz. Bu olaylar, genellikle iş mantığının bir sonucu olarak ortaya çıkar ve uygulamanın farklı parçaları arasında iletişimi sağlamak için kullanılırlar. Ayrıca terminolojik olarak domain event’lerin tetiklenmesini Raising kavramıyla ifade etmeyi tercih ederiz. Yani bir sipariş oluşturulduğunda ‘OrderCreatedEvent’ event’ini tetiklemeyiz de, raise etmiş oluruz… 🙂 Ha tabi çok isterseniz ‘tetikleme’ terimini de kullanabilirsiniz…

Şimdi domain event’lerin raising edilmesi için bazı yaygın noktaları ele alalım;

Nihai olarak;
Domain event’ler eşliğinde, uygulama bünyesindeki bileşenler arasında loosely coupled(gevşek bağlı) davranışlar sergileyebilir ve domain logic’i asenkron süreçlerdeki olası yan etkilerden arındırarak çalışmalarımızı rahatlıkla gerçekleştirebiliriz. Bu içeriğimizde bu durumları teorik olarak masaya yatırmaya çalışıp, pratiksel olarakta mümkün mertebe tecrübe etmeye çalışmış bulunuyoruz.

İlgilenenlerin faydalanması dileğiyle…
Sonraki yazılarımda görüşmek üzere…
İyi çalışmalar…

Not : Örnek projeyi aşağıdaki github adresinden edinebilirsiniz.
https://github.com/gncyyldz/Loosely_Coupled_Systems_Domain_Events_Examples

Mobil sürümden çık