Bu sorgular iyi bir mimarinin neresine sığar?

Aug 17 2020

Bir süredir bir problem hakkında düşünüyordum ve buna nasıl yaklaşacağımı gerçekten düşünmüyorum.

Mümkün olduğunca DDD ile çalışmaya çalışıyorum ama bazı sunum senaryoları performans açısından buna pek uymuyor.

Diyelim ki kiralık arabalar için bir sistemimiz var ve orada tüm araçları ve kaç kez kiralandıklarını gösteren bir görünümümüz var.

Bir DDD dünyasında, sanırım kiralık arabalarım için bir depom ve "kiralamalar" için bir miktar depom olacaktı. Bir de aralarındaki etkileşimi işleyen, anlaşmalar oluşturan bir hizmetin olabileceğini tahmin ediyorum.

Ama kiralık arabalar ve kira sayısı ile manzarayı sunmaya gelince, bunu nereye koyacağımdan pek emin değilim. Gereksinimler bu görünüme çok özel olduğundan, sanırım en yüksek performanslı sürüm arşiv tarafından döndürülen bir tür "RentalCarsOverview" nesnesine sahip olmak olacaktır. Ancak bu, depoları görünüme çok özel sorgularla "kirletebilir".

Öyleyse merak ediyorum da aynı sorunlarla karşılaşan var mı ve nasıl çözüldü? Bu tür görünümler için sorguları ve güncellemeler için alan modelimi kullanarak bunu ayırmak için CQRS'ye bakıyordum. Bu iyi bir yaklaşım mı?

Ayrıca, bu sorgu işleyicilerinde yalnızca ham SQL olması "uygun" olur mu, yoksa bunları temeldeki bir havuzla da soyutlamak mı?

Yanıtlar

3 VoiceOfUnreason Aug 17 2020 at 19:44

Bu günlerde olağan yanıt, sorgu kodu yollarınızın "etki alanı modelini" atlayacağı ve doğrudan bilgilerinizin kopyalarıyla çalışacağıdır.

Buradaki argüman, bir sorgunun alan modelinde depolanan bilgileri değiştirmemesidir ve bu nedenle, bu bilgileri yalnızca onları tekrar çıkarmak için alan nesnelerine yerleştiren bir dizi törenden yararlanmıyoruz.

Örneğin, tüm bilgileriniz aynı ilişkisel veritabanında depolanıyorsa, veritabanını sorgulamanız ve sonuç kümelerindeki bilgileri doğru şekle dönüştürmeniz ve bunu istemciye geri göndermeniz daha olasıdır.

Sorguyu cevaplamak için ihtiyaç duyduğunuz bilgi birden fazla sisteme dağıtıldığında, raporu oluşturmak için daha fazla ısmarlama çalışma olur. Raporu oluşturmak için gereken süre gecikme hedeflerinizi aştığında, raporun pahalı kısımlarını önbelleğe alabileceğiniz tasarımlara bakmaya başlarsınız . Bazı durumlarda bu, tüm raporun önbelleğe alındığı anlamına gelir.

2 RikD Aug 17 2020 at 17:07

CQRS ve DDD mükemmel bir eşleşmedir.

Komutlar, depolarınız ve DDD modelleriniz aracılığıyla gider. Sorgular, her görünüm için özel olarak ayrı modellerle ham SQL veya hafif bir ORM olabilir.

Sisteminizi bu şekilde tasarlamak, okumalar için mümkün olan en iyi performansla karmaşık iş kurallarının üstesinden gelmek için size sağlam bir yol sağlar.

2 CarmineIngaldi Aug 17 2020 at 19:38

Akıllı sorgulara sahip olmanın bir DDD kod kokusu olduğunu göstermeye başlayalım. Çoğu zaman yapmanız gereken tek şey

  • kimliğine göre bir toplam alın (RESTful konuşuyor: GET / users / xyz)
  • belirli bir kök ile tüm toplamaları al (/ users? page = 0 & limit = 10)
  • basit bir filtreyle toplamaların bir alt kümesini alın (RESTful'dan bahsederken: GET / users? username_startsWith = johnd & page = 0 & limit = 10)

Karmaşık uygulamaların karmaşık şeyler yapması gerekir, bu nedenle sonunda kümenizden projeksiyonlar oluşturmanız gerekebilir . Açıkçası, kümeniz bir projeksiyonun ne olduğuna dair herhangi bir fikre sahip olmamalıdır, ancak bunları oluşturmak için gerekli tüm verileri orada bulabilirsiniz, çünkü alanınızı yalnızca tutarlı bir şekilde mutasyona uğramak için değil, aynı zamanda gözetilecek şekilde tasarlıyorsunuz

Bu, CQRS kavramlarını tanıtmadan bile makul bir yaklaşımdır. Uygulamalarımızın çoğu CRUD uygulamaları + bazı alan doğrulama kurallarıdır. Gereksinimlerinizde / öykülerinizde / kodunuzda " genel bakış " " rapor " " istatistik " " özet " " geçmiş " gibi sözcüklerle karşılaşırsanız , bunları yalnızca belirli sorgular aracılığıyla toplamaları belleğe yükleyerek ve bazı kümelemeleri çağırarak yönetebileceğinizi bilirsiniz. yöntem (sayımlar, toplamlar, ortalamalar) e bazı projeksiyon DTO'larına karşı eşleme yapın

Yukarıda belirtilen durumlar projenizde öne çıktığında, yalnızca bazı toplu bilgileri almak için kümeleri yüklerken sisteminiz için büyük bir yük olur, bu nedenle evet, CQRS'nin yararlı olduğu iki kullanım durumundan birini karşılıyorsunuz

Kayda değer bir durum mutasyonu her gerçekleştiğinde, toplamınıza (yani, yazma tarafı toplama) etki alanı olaylarını tetikleme yeteneği sağlayacaksınız.

Projeksiyonlarınızı güncellemek ve kaydetmek için projeksiyona özel depolara ve olay işleyicilerine (sizin durumunuzda onEvent (CarRentedOutEvt evt) gibi bir şey) sahip olacağınız farklı bir modül oluşturacaksınız .

Çok aptalca davranacak bir GET / kira / genel bakış yönetici API'sine sahip olacaksınız (yine rahat bir şekilde konuşursak).

Merrion Sep 08 2020 at 17:48

Birden fazla okuma modeline ve bu durumda, bir "Kiralanmış" olayı aldığında kendini güncellemek için gereken olaylara abone olan normalleştirilmiş "Raporlama" okuma modeline sahip olmanıza izin verilir.