Anemik etki alanı modeli bir karşıtlık mı? Zengin alan modelleri mi kullanıyoruz? [kapalı]


11

Anemik alan modeli, görünüşe göre nesne yönelimli ilkelere, vb. Yönelik olduğu için Evans ve Fowler tarafından uzun zaman önce eleştirildi . DDD topluluğu bu ifadelerle açıkça hizalanmıştır.

Bununla birlikte, son yıllarda bunun bir anti-patlayıcı olmadığını ve aşağıdaki SOLID ilkelerinin bir örneği olduğunu iddia eden sesler katılmıyordu.

Spring Framework kullanarak uzun yıllardır çalışıyorum. Her şirketteki her proje, her zaman anemik modellerde (JPA varlıkları) çalışan depoları kullanarak iş mantığını içeren bir hizmet katmanına sahiptir. Dahası, örneklerin çoğu, hatta Bahar adamlarından resmi olanlar bile, bu çalışma biçimini sergiliyor.

Sorularım: Anemik alan modeli hala bir karşıtlık olarak kabul ediliyor mu? Hepimiz (DDD ile ilgili) bir şeyler yanlış mı yaptık? Rich Domain modellerine sahip olmanın SOLID ilkelerini ihlal ettiğini düşünmüyor musunuz?


2
" Anemik etki alanı modeli hala bir karşıtlık olarak kabul ediliyor mu? " Bazıları tarafından, evet. Başkaları tarafından, ben de dahil, çoğu zaman kod yazmanın tercih edilen yolu olarak görüyoruz, ancak RDM size uygunsa, onu kullanın. Bu yüzden bunu tamamen fikir tabanlı olarak kapatmak için oy kullanmak.
David Arno

1
Bu bir tartışma / tartışma forumu için harika bir soru olurdu; ancak şu anda yetkili bir cevap yok. Sadece tartışmakla kalmayıp cevaplanabilecek soruları tercih ediyoruz.
VoiceOfUnreason

Yanıtlar:


9

ADM, mikro hizmetler gibi dağıtılmış hizmetlerin çözümü için iyi bir modeldir. Günümüzün web tabanlı iş örneklerinin çoğuna uyar.

Sipariş Etki Alanı nesnesimiz olup olmadığını düşünün. Bir OOP yaklaşımı ile Order.Purchase () Order.Cancel () vb.

Ancak, dağıtılmış bir sistemimiz varsa, sadece bir şeye sahip olan programlara sahipsek, yani bir sipariş listesine erişip her birini sırayla satın alın veya sırayla bir sipariş listesi alın ve her birini iptal edin, ardından aynı nesnede her iki Metot da duygusu. İki Alan veya Sınırlı Bağlamımız olması gerekir:

PurchaseSystemOrder.Purchase()

ve

CancelSystemOrder.Cancel();

Bu nesnelerin paylaşacağı tek şey özelliklerin veri yapısı olacaktır.

Giderek daha fazla mikro hizmet ekledikçe, düzinelerce sipariş türü elde edersiniz. Artık tüm bu sistemler tarafından işlenen aynı kavramsal düzen olmasına rağmen, bir Etki Alanı nesnesi olarak bir Sipariş hakkında konuşmak mantıklı değildir .

Sadece verileri kapsayan ve hizmetlerinizi buna göre yeniden adlandıran bir Anemik model olan Order'a sahip olmak çok daha mantıklıdır:

PurchaseService.Purchase(Order order)

Şimdi Sipariş hakkında tekrar konuşabiliriz ve şu anda konuşlandırılan diğer hizmetleri etkilemeden işlemek için düşündüğümüz yeni hizmetleri ekleyebiliriz.

Fowler ve Co, yekpare bir sistem geçmişinden geliyor, dünyalarında bir ADM yaklaşımı, bellekte somutlaştırılan tüm bu ayrı hizmetlerin ve OrderDTO'nun aktarıldığı ve mutasyona uğradığı tek bir uygulama anlamına geliyor. Bu, yöntemleri zengin bir Sipariş modeline koymaktan çok daha kötü olurdu.

Ancak dağıtılmış bir sistemde, her biri yalnızca tek bir Sipariş yöntemi gerektirir ve her birini yükleyerek, yöntemi çalıştırıp sonra atarak birçok program çalıştırır. Yalnızca tek bir Hizmet ve bir veri nesnesi akışı gerektirir.

Zengin bir modeli tam olarak doldurmak, tüm Yöntemlerin gereksinimlerini ve bağımlılıklarını sadece tek bir tane çağırmak ve daha sonra nesneyi hemen atmak için endişelenmek anlamsızdır.

Ayrıca yöntemlerden birinde yapılan bir değişiklik, mantıklarının tümü Zengin Model'e bağlı olduğu için tüm dağıtılmış bileşenlerin güncellenmesini gerektirecektir.

Kod üslerimde ihtiyaç duymadıkları şeyler için yerim yok


4
Düşürdüm, çünkü DDD'nin özellikle sınırlı bağlam konsepti nedeniyle mikro hizmetlere çok uygun olduğunu düşünüyorum. Cevabınızla ilgili sorun, Sipariş kavramının ve sınıfın her mikro hizmette aynı olacağı, ancak bunun ne gerekli ne de doğru olduğunu düşünüyorum.
RibaldEddie

Kabul etmiyorum, PurchaseService CashRegister'ınızı arar ve etki alanı dilinizin bir parçası yaparsanız ADM DDD olabilir
Ewan

detaylandırabilir misin Ben her zaman ADMM ve DDD bir SOLID J2EE veya .NET C # MVC EF kod tabanında olduğunu YMMV düşündüm.
RibaldEddie

Demek istediğim, sınırlı bağlam Order, PurchaseSystemOrder.Purchase (), CashRegister.Purchase (Order order) için sadece aynı etki alanı dilindeki bir adlandırma değişikliği olacaktır. Zengin alan adı modeli, aynı sınıfta hem Satın Alma hem de İptal yöntemlerine sahip olmak anlamına gelir.
Ewan

1
@RibaldEddie, "javaScript, iyi parçalar" kitabının kalınlığına bağlı olarak, bu görüntüyü mikro hizmetlerin uygulanması için DDD kullanımına karşı (tamamen ciddi değil) bir argüman olarak sunuyorum ;)
David Arno

3

SOLID ve DDD birbirine diktir, yani birbirlerinden gerçekten farklı yönlere gidiyorlar. Birinin diğerinin dışlanmasına alışık olduğunu söylememelisiniz, çünkü aynı kod tabanında birlikte olabilirler ve muhtemelen var olmalıdırlar.

Anemik etki alanı modelleri, sorun etki alanınız çok fazla davranışa sahip olduğunda ve hizmet katmanı yöntemlerinin bir şey yapmak için diğer hizmet katmanı yöntemlerini çağırması gereken çok sayıda kopya yapıştırılmış mantık veya bağımlılığa sahip yüzlerce hizmet yönteminiz olduğunda bir anti-desen haline gelir.

DDD, sınırlı bağlam konsepti nedeniyle mikro hizmetler için mükemmel bir paradigmadır .

Altyapı kodunu alan adınızın bir parçası olarak görme ayarına dikkat edin. Altyapı kodu, kendiniz yazmadığınız veya üçüncü taraf bir sistemle etkileşime giren bir çerçeveye veya kitaplığa bağlı herhangi bir şeydir. Veritabanı bağlantıları, SMTP postaları, ORM kütüphaneleri, uygulama sunucusu çalışma süreleri, tüm bu şeyler altyapıdır ve bundan kaçınabilmeniz için etki alanınıza dahil edilmemeli veya buna güvenmemelisiniz.

SOLID ilkeleri, daha iyi OOP kodu oluşturmak için kullanabileceğiniz bir dizi genel amaçlı OOP kavramlarıdır. Bunları kullanarak iyi bir DDD kod tabanı yazabilirsiniz.


Altyapı kodunun alan adından ayrılması ile ilgili. Şimdiye kadar, aşağıdaki uygulama katmanlarına sahip alan adımı JPA varlıkları olarak kabul etmiştim: denetleyici -> hizmet -> depo -> etki alanı (JPA Varlıkları). Anladığınız noktaya göre modellemenin doğru (veya sağdan biri) yolları nelerdir? Şuna benzer: denetleyici -> zengin model -> x? İşlemselliği nasıl ve nerede ele alırım? Peki ya JPA Haritalaması? Zengin modelimizi ayrılmış JPA varlıklarıyla çoğaltmamız gerekmez mi?
bağlaşık

Bir JPA varlığı, eski bir Java nesnesidir. Haritalama altyapının bir parçasıdır, ancak sınıfın kendisi olmak zorunda değildir. Altyapının bir parçası olarak ele almayı seçerseniz, bunu bir etki alanı Varlığı oluşturmak için Fabrikada veya Havuzda kullanılan bir veri aktarım nesnesi olarak düşünmelisiniz.
RibaldEddie

1

Zengin bir alan iyi yapıldığında güzeldir. Değilse bir kabus. Anemik bir alan her zaman kötüdür. Ama bu tanıdık rahat bir tür kötü.

Anemik etki alanı istediğiniz her şeyse, genel amaçlı bir dil seçtiğinizde yanlış dili seçersiniz. 4. nesil diller belirli bir kullanım için uzmanlaşmıştır. Anemi yeterince iyi kullanılsaydı hayatınızı kolaylaştıracaktı.

Birçok çerçeve, işi artık bir java işi olarak ilan edinceye kadar dil alanına girer. Bu bir Java / Bahar işi. Yaptıkları şey, sizi onlara bağımlı kılmanın yanı sıra, genel amaçlı bir dili 4. nesil bir dilin piç biçimine dönüştürmektir.

Bu en iyi yöntem mi yoksa anti-desen mi? Peki patronunuz çoğunlukla sadece kod bazında çalışmak için insanları işe alıp alamayacağınıza önem veriyor. Yani rol yapmak zorunda kalırsak, insanları işe almak için genel amaçlı bir dil kullanırız.

Eğer onunla ok o zaman iyi. Kesinlikle tek kişi sen değilsin.

Ama bana bunun böyle olması gerektiğini söyleme. Bana benim için olduğundan daha fazla bir şey yaptığını söyleme. Onsuz nasıl yaşayacağımı biliyorum. Bunu nasıl zorlayacağımı biliyorum, sadece birkaç şey buna bağlı. Benden teslim etmemi ve sadece kavga etmek zor olduğu için her şeyi devralmasına izin veriyorsanız, evet bence bu kötü.

İhtiyaç duymadığım şeyler için kod tabanımda yer yok.

SOLID ve diğer tasarım ilkelerine gelince, anemik bir alanda bile bunları büyük ölçüde takip edebilirim. Onları takip etmemek farklı bir soruna neden olur.


Cevabınızı takdir ediyorum ve Spring veya JPA-Hibernate gibi bazı çerçevelerin Java manzarasını fethettiğini kesinlikle kabul ediyorum. Bununla birlikte, Java'nın (JEE) hiç ele almadığı veya yanlış yaptığı bir dizi iyi uygulama ve basitleştirme sağladıkları inkar edilemez. DDD konusunda gerçekten hevesliyim ve söyledikleri tüm ilkeleri anlamak istiyorum. deneyim, saf DDD uygulamaları (Zengin Etki Alanı Modelleri ile) ile çalışmak için en iyi platformlar / diller / çerçeveler nelerdir? Söylediğin gibi işleri iyi yapmak istiyorum, kötü uygulamalara uymamak.
bağlaşık

Burada kaynak önerileri yapmıyoruz. Ancak, çerçevelerle ilgilenen uygun bir altyapı katmanının, istediğiniz herhangi bir türü kullanabileceğiniz anlamına geldiğine inanıyorum. Onlara kütüphane gibi davran. Bunların bilgilerini alan adından uzak tutun. Ayrıca, sihire güvenmeyin. Kendinize yapamayacağınız şeyleri kullanma dürtüsüne karşı koyun. Çünkü bir gün ihtiyacın olabilir.
candied_orange

Orijinal noktaya geri dönüyoruz. SOLID ilkeleri ne olacak? Zengin alan modelleri birçok sorumluluk, kalıcılık (JPA), iş mantığı (işlemle uğraşmak zorunda kalıyor) vb. Sesleri de test etmek daha kolay. O zaman bu kadar yanlış olan ne?
bağımsız

Ana şey, semantik ihtiyaçlardan ziyade sistem ihtiyaçlarına göre tasarım seçimleri yapmaya başlamanızdır. İnce, göz ardı edilmesi kolay, maliyet açık ve düzeltmeyi haklı çıkarmak zor değil. Kısacası elektrik hatlarının sandık yerine gömülmesi gerektiğini savunmak gibi. İnsanlar cıvıltı alternatifine alıştıktan sonra değişme olasılığı yoktur. Kasırgalar gücü kestiğinde bile.
candied_orange

1
"Zengin bir alan iyi yapıldığında güzel. Değilse bir kabus" iddianızla ilgili şüphenizden faydalanacağım. Belki de hiç iyi bir iş çıkardığını hiç görmedim, Ama sonra saçma bir iddiada bulunuyorsun, "Anemik bir alan her zaman kötü." Görüşlerinizi saçma sapan değersiz hale getirir. -1
David Arno
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.