Bilgisayarlı Değerler ve Basit Okumalar - Etki Alanına Dayalı Tasarımlarım için rahatsız edici bir acı!


9

Sürekli karşılaştığım sorun, veri deposuna karşı hala verimli bir şekilde çalışırken alan mantığı tarafından yönlendirilen hesaplanmış değerlerle nasıl başa çıkılacağıdır.

Misal:

Bir hizmet aracılığıyla havuzumdan bir Ürün listesi döndürüyorum. Bu liste, istemci tarafından gönderilen DTO isteğindeki sayfalandırma bilgileriyle sınırlıdır. Ek olarak, DTO bir sıralama parametresi (istemci dostu bir numaralandırma) belirtir.

Basit bir senaryoda, her şey harika çalışır: hizmet repo'ya disk belleği ve sıralama ifadeleri gönderir ve repo DB'ye verimli bir sorgu gönderir.

Ancak, etki alanı modelimden bellekte oluşturulan değerleri sıralamamız gerektiğinde tüm bunlar bozulur. Örneğin, Product sınıfı, iş mantığına dayalı bir bool döndüren bir IsExpired () yöntemine sahiptir. Şimdi repo seviyesinde sıralayamıyorum ve sayfa yapamıyorum - hepsi bellekte (verimsiz) yapılacaktı ve hizmetim bu paraşütleri ne zaman repo'ya vermenin ve ne zaman sıralama / sayfalama yapmanın karmaşıklıklarını bilmek zorunda kalacaktı kendisi.

Bana mantıklı gelen tek örüntü db'de varlığın durumunu saklamak (IsExpired () 'i salt okunur bir alan haline getirmek ve kaydetmeden önce etki alanı mantığı üzerinden güncellemek). Bu mantığı ayrı bir "okuma modeli / dto" ve "raporlama" deposuna ayırırsam, modelimi istediğimden daha anemik hale getiriyorum.

BTW, bunun gibi hesaplamalar için orada gördüğüm her örnek, bellek içi işlemeye ve uzun vadede çok daha az verimli olduğu gerçeğine odaklanıyor. Belki zamanından önce optimizasyon yapıyorum, ama bu sadece bana uygun değil.

DDD içeren neredeyse projede yaygın olduğundan emin olduğum için başkalarının bununla nasıl başa çıktığını duymak isterim.

Yanıtlar:


3

Aynı veri modeline sahip iki farklı alan adı modeline sahip olmanın alan adınızı anemik hale getirdiğini düşünmüyorum. Anemik etki alanı modeli, sık sık değişen iş mantığının bir hizmet katmanındaki (veya daha kötüsü UI katmanındaki) etki alanından uzakta saklandığı modeldir.

Komut ve sorgu etki alanı modellerinin ayrılması sıklıkla benimsenir ve CQRS'de (Komut Sorgusu Sorumluluk Ayrımı) Google'ı kullanabileceğiniz hoş bir kısaltmaya sahiptir.

Alan Modeli Modelini Kullanmak, Udi Dahan

Geçmişte hem komutları hem de sorguları işleyen tek bir kalıcı nesne modeli oluştururken "başarılı" olmama rağmen, sistemin her bir parçası modeli farklı bir yöne çektiğinden, ölçeklemek genellikle çok zordu.

Geliştiricilerin genellikle işletmenin gerçekten ihtiyaç duyduğundan daha zorlu gereksinimleri üstlendiği ortaya çıkıyor. Etki alanı model varlıklarını kullanıcıya bilgi göstermek için kullanma kararı böyle bir örnektir.

[...]

Hatırlanacak kadar yaşlılar için, COM + 'yı kullanmayla ilgili en iyi uygulamalar, bizi salt okunur ve okuma-yazma mantığı için ayrı bileşenler oluşturmamıza yönlendirdi. On yıl sonra, Varlık Çerçevesi gibi yeni teknolojilerle karşınızdayız, ancak aynı ilkeler devam ediyor.

Akka oyuncuları ve fonksiyonel alan modelleri ile CQRS, Debasish Ghosh

Greg Young DDD ve CQRS ile ilgili harika seanslar verdi. 2008 yılında "Tek bir model raporlama, arama ve işlem davranışı için uygun olamaz" dedi. En az iki modelimiz var - biri komutları işleyen ve değişiklikleri kullanıcı sorguları ve raporları sunan başka bir modele besleyen. Uygulamanın işlemsel davranışı, kümelerin ve depoların zengin etki alanı modeli aracılığıyla yürütülürken, sorgular doğrudan normalize edilmemiş bir veri modelinden sunulur.

CQRS, Martin Fowler

CQRS'nin getirdiği değişiklik, bu kavramsal modeli, CommandQuerySeparation kelime dağarcığını takiben sırasıyla Command ve Query olarak adlandırdığı güncelleme ve görüntüleme için ayrı modellere bölmektir. Bunun mantığı, birçok sorun için, özellikle daha karmaşık alanlarda, komutlar ve sorgular için aynı kavramsal modele sahip olmanın, ikisi de iyi olmayan daha karmaşık bir modele yol açmasıdır.

Kısacası, komut modelinin son kullanma tarihini işlemesi ve veritabanına geçirmesi fikriniz kesinlikle iyidir. Yukarıdaki ilk makaleyi okuyun ve benzer ancak daha karmaşık senaryolar göreceksiniz.


2

ŞARTNAME

Zaten bir yanıtı kabul ettiğinizi biliyorum, ancak DDD hakkında sorular sordunuz ve bunun için tam eşleşme Evans'ın 'spesifikasyon' olarak adlandırdığı şeydir:
doğrudan google kitaplar bağlantısı
Bu bağlantı işe yaramazsa bu sonuçlarda kitap olup olmadığını kontrol edin
Kitabınız varsa sayfa 226.

227 Sayfasında belirtimler için 3 kullanımı vardır: Doğrulama, Seletion, Yeni bir özel nesne oluşturma. Seninki 'seçim' - Süresi doldu.

'Specicaiton' konsepti ile ilgili başka bir şey, verimlilik açısından - bellek içi nesnelerde çalışmak için bir kod sürümüne ve ilk almak zorunda kalmadan depoyu verimli bir şekilde sorgulamak için kodun başka bir sürümüne ihtiyacınız olabileceğini kabul etmesidir. tüm nesneleri hafızaya.

Basit bir dünyada bu, deponuza bir SQL sürümü ve modelinizde elbette dezavantajları olan bir nesne sürümü koymak anlamına gelir. Mantık 2 yerde (kötü, birisi bu yerleri güncellemeyi unutacak) ve deponuzda etki alanı mantığı var.

Bu yüzden cevap, her iki mantık kümesini de bir spesifikasyona koymaktır. Bellek içi sürüm, tabii ki, aynı zamanda bir depo sürümü. Örneğin n-hazırda bekletme modunu kullanıyorsanız, depo sürümü için yerleşik sorgu dilini kullanabilirsiniz.

Aksi takdirde, belirtim nesnesinden kullanılan bu belirtim için özel bir havuz yöntemi oluşturmanız gerekir. Spesifikasyonla eşleşen nesnelerin toplanması için yapılan çağrılar, depodan değil spesifikasyondan geçer. Ve en azından kod gelecekteki koruyucular için '2 yerdeyim, unutma' diye bağırıyor. Çok benzer bir sorunu çözmek için 231-232. Sayfada harika bir örnek var.

Spesifikasyon, DDD'nin 'saflığının' 'izin verilen' bir sızıntısı / kaymasıdır. Yine de, çeşitli amaçlarla ihtiyaçlarınızı karşılamayabilir. Örneğin, ORM hatalı SQL üretebilir; fazladan kodlama olabilir. Bu nedenle, neredeyse SQL'i belirtime koymak gibi bir havuz yöntemi çağırmanız gerekebilir. Tabii kötü bir şey. Ancak unutmayın, programınız makul bir hızda çalışmalıdır. DDD saflık ödülü kazanmak zorunda değil. Bu nedenle, veri depolarını değiştirme gerçekliği, program boyunca eski moda cerrahi anlamına gelebilir. Ayrıca kötü bir şey. Ama yavaş (aka SUCKing) bir program kadar kötü değil. Çeşitli DB'lerde kutunun bitmesi bir gerçekse, her spesifikasyon için her veri deposu için iş kurallarını çoğaltacaksınız. En azından konu üzerinde parmağınız var ve depoları değiştirirken strateji modelini kullanabilirsiniz. Ancak belirli bir DB kullanıyorsanızYAGNI.

CQRS ile ilgili olarak: Fowler'in yukarıdaki pdr tarafından yaptığı alıntı burada hala geçerlidir: "komutlar ve sorgular için aynı kavramsal modele sahip olmak, ne iyi olan daha karmaşık bir modele yol açar" ... ve CQRS veya benzerlerini kullanmanız gerekebilir. Ancak geliştirme ve bakım açısından çok daha pahalıdır. Başkalarıyla rekabet eden bir paket satıcısıysanız, ödeyebilir. Bir müşteri için özel bir LOB uygulaması yazıyorsanız, mükemmellik için çekim yapmak kötü bir seçimdir. Tamamen veya çoğunlukla çift modele sahip olmanın değerinin ekstra çabaya değip değmeyeceğine karar vermeniz gerekir. Şartnameiyi bir uzlaşmadır, çünkü bu ayrımı tek bir modelin (geliştirme) hızı ve basitliğiyle programa ihtiyaç duyan programın sadece küçük bir kısmında yapmanıza izin verir. İyi şanslar!


Bu çok mantıklı. Sanırım kurşunu ısırmam ve Evans'ın kitabını okumam gerekiyor :-) Şimdi görüyorum ki, bu kavramlar hakkında sığ bir anlayışa sahip olmak seni gerçekten felç edebilir!
drogon

0

İsExpired'in doğru olup olmadığını belirleyen iş mantığının ne olduğunu sorgulayacağımı tahmin ediyorum. Bu mantık, veri modeli durduğunda bir sorgu tarafından gerçekleştirilebilir mi? Öyleyse, deponuzu belirli bir şekilde Ürünler için sorduğunuzda "isExpired" mantığını kullanacak kadar akıllı hale getirebilir misiniz? Değilse, belki de veri modelinizi yeniden incelemeniz gerekir.

DDD, depolarınızın aptal olması gerektiği anlamına gelmez - bu sadece alan adınızın depolarınızla nasıl konuşacağınızı bilmesi gerektiği anlamına gelir.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.