it-swarm.asia

Tüm bu hizmetlerle nasıl anemik olamazım?

Yetkilendirme ile iş mantığının kapsüllenmesi arasındaki çizgiyi nerede çiziyoruz? Bana öyle geliyor ki, ne kadar çok temsilci seçersek o kadar çok anemik oluruz. Ancak, temsilci seçme aynı zamanda yeniden kullanımı ve DRY anapara) teşvik eder. Peki, temsilci seçmek için uygun olan nedir ve alan modellerimizde ne kalmalıdır?

Aşağıdaki endişeleri örnek olarak ele alalım:

Yetkilendirme . Etki alanı nesnesi, erişim denetimi kurallarını (CanEdit özelliği gibi) korumaktan sorumluysa veya erişimi yönetmekten yalnızca başka bir bileşene/hizmete devredilmişse, ör. IAuthorizationService.CanEdit (nesne)? Yoksa ikisinin bir kombinasyonu mu olmalı? Belki de domain nesnesinin, gerçek işi gerçekleştirmek için dahili bir IAuthorizationService'e temsilci atayan bir CanEdit özelliği vardır?

Doğrulama . Yukarıdaki tartışma aynı doğrulama ile ilgilidir. Kuralları kim korur ve değerlendirmekten kim sorumludur? Bir yandan, nesnenin durumu o nesneye ait olmalıdır ve geçerlilik bir durumdur, ancak her etki alanı nesnesi için kuralları değerlendirmek için kullanılan kodu yeniden yazmak istemiyoruz. Biz olabilir bu durumda miras kullanıyoruz ...

Nesne Oluşturma . Fabrika sınıfına karşı fabrika yöntemlerine karşı 'yeni' bir örnek. Ayrı bir fabrika sınıfı kullanırsak, yaratma mantığını yalıtabilir ve kapsülleyebiliriz, ancak nesnemizin durumunu fabrikaya açma pahasına. Bu, etki alanı katmanımız fabrika tarafından kullanılan dahili bir kurucu açığa çıkarılarak ayrı bir Montajdaysa yönetilebilir, ancak birden fazla oluşturma deseni varsa bu bir sorun haline gelir. Ve eğer tüm fabrika yapıyorsa doğru kurucu diyorsa, fabrikaya sahip olmanın anlamı nedir?

Sınıftaki fabrika yöntemleri, nesnenin iç durumunu açma konusundaki sorunu ortadan kaldırır, ancak statik olduklarından, ayrı bir fabrika sınıfında olduğu gibi bir fabrika arabiriminin enjekte edilmesi yoluyla bağımlılıkları kıramayız.

Kalıcılık . Etki alanı nesnemiz, yetkilendirme denetimini başka bir tarafa (IAuthorizationService) gerçekleştirme sorumluluğunu devrederken CanEdit'i ortaya çıkaracaksa, neden aynı şeyi yapan etki alanı nesnemizde bir Kaydetme yönteminin bulunmadığı iddia edilebilir. Bu, işlemin kapsüllemeyi kesmeden gerçekleştirilip gerçekleştirilemeyeceğini belirlemek için nesnenin dahili durumunu değerlendirmemize olanak tanır. Tabii ki, depo örneğini alanım nesnesine enjekte etmemizi gerektiriyor, bu da bana biraz kokuyor, bu yüzden bunun yerine bir alan adı olayı oluşturuyor ve bir işleyicinin kalıcılık işlemini gerçekleştirmesine izin veriyor muyuz?

Bununla nereye gittiğimi gördün mü?

Rockford Lhotka, CSLA çerçevesi için Ücretli Sınıf rotasına gitme nedenleri hakkında harika bir tartışmaya sahip ve bu çerçeveyle biraz geçmişim var ve iş nesneleri fikrini alan nesnelerine birçok yönden paralel olarak görebiliyorum. Ancak iyi DDD ideallerine daha bağlı olmaya çalışırken, işbirliğinin ne zaman çok fazla olacağını merak ediyorum.

Toplam köküm için bir IAuthorizationService, IValidator, IFactory ve IRepository ile karşılaşırsam, geriye ne kaldı? Sınıfın anemik olmayan bir etki alanı nesnesi olduğunu düşünecek kadar nesnenin durumunu Taslak'tan Yayınlandı olarak değiştiren bir Publish yöntemine sahip misiniz?

Senin düşüncelerin?

92
SonOfPirate

Karışıklıkların çoğu, etki alanı modelinde bulunmaması gereken işlevsellik etrafında görünüyor:

  • Kalıcılık asla etki alanı modelinde olmamalıdır. Asla asla. Bu nedenle, modelin bir kısmının modelin farklı bir bölümünü almak gibi bir şey yapması gerekiyorsa IRepository gibi soyut türlere güvenmeniz ve uygulamayı bağlamak için bağımlılık enjeksiyonu veya benzer bir teknik kullanmanız gerekir. Yani kayıttan vur.

  • Yetkilendirme, alan adınızın bir parçası değilse, alan adınızın bir parçası değilse genellikle değildir; güvenlik yazılımı yazıyorsanız. Bir uygulamada kimin ne yapmasına izin verildiği mekaniği, normalde iş/alan katmanının "Ucu" nda, UI ve Entegrasyon parçalarının gerçekte konuşmasına izin verilen genel bölümlerde ele alınır - MVC'deki Denetleyici, Hizmetler ya da mesaj sisteminin kendisi bir SOA'da ... resmi elde edersiniz.

  • Fabrikalar (ve buradaki soyut fabrikaları kastettiğinizi varsayalım) tam olarak kötü bir alan adı modeline sahip değiller, ancak neredeyse her zaman gereksizdirler. Normalde bir fabrikanız yalnızca nesne yaratmanın iç mekaniği değişebileceği zaman olur. Ancak etki alanı modelinin yalnızca bir uygulaması vardır, bu da her zaman aynı yapıcıları ve diğer başlatma kodunu çağıran sadece bir tür fabrika olacağı anlamına gelir.

    İsterseniz "kolaylık" fabrikalarına sahip olabilirsiniz - yapıcı parametrelerinin ortak kombinasyonlarını kapsayan sınıflar vb. - ama dürüst olmak gerekirse, genel olarak konuşursak, alan modelinizde oturan çok fazla fabrikanız varsa, o zaman sadece israf ediyorsunuz kod.

Bunların hepsini bir kez çimdiklediğinizde, bu sadece onaylama bırakır. Zor olan tek kişi bu.

Validation is alan modelinizin bir parçası, ancak aynı zamanda uygulamanın diğer tüm bileşenlerinin bir parçasıdır. Kullanıcı arayüzünüzde ve veritabanınızda benzer ancak farklı bir kavramsal modele dayanan kendi benzer, ancak farklı doğrulama kuralları olacaktır. Nesnelerin Validate yöntemine sahip olması gerekip gerekmediği gerçekten belirtilmez, ancak yapsalar bile, genellikle bir doğrulayıcı sınıfına devrederler (arabirim değil - doğrulama değil özet etki alanı modelinde temeldir).

Doğrulayıcının teknik olarak hala modelin bir parçası olduğunu unutmayın; herhangi bir veri veya durum içermediğinden toplu bir köke bağlanması gerekmez. Etki alanı modelleri, genellikle bir Meclise veya bir meclis koleksiyonuna fiziksel olarak tercüme edilen kavramsal şeylerdir. Temsilci kodunuz nesne modeline çok yakınsa, "anemik" sorun üzerinde durmayın; hala önemli.

Tüm bunlar gerçekten ortaya çıkıyor, eğer DDD yapacaksanız, olduğunu alan adını anlamak zorundasınız. Hala inat ve yetkilendirme gibi şeylerden bahsediyorsanız, yanlış yoldasınız demektir. Etki alanı, bir sistemin çalışma durumunu temsil eder - fiziksel ve kavramsal nesneler ve öznitelikler. Nesneler ve ilişkilerle doğrudan ilgili olmayan herhangi bir şey alan adı modeline, döneme ait değildir.

Genel bir kural olarak, bir şeyin alan adı modeline ait olup olmadığını düşünürken kendinize şu soruyu sorun:

"Bu işlevsellik yalnızca teknik nedenlerle değişebilir mi?" Başka bir deyişle, gerçek dünyadaki iş veya etki alanında gözlemlenebilir bir değişiklik nedeniyle değil mi?

Cevap "evet" ise, alan modeline ait değildir. Alan adının bir parçası değil.

Bir gün, kalıcılığınızı ve yetkilendirme altyapılarınızı değiştirme şansınız çok yüksektir. Bu nedenle, alan adının bir parçası değil, uygulamanın bir parçasıdır. Bu, sıralama ve arama gibi algoritmalar için de geçerlidir; Etki alanınızın modeline bir ikili arama kodu uygulaması gitmemelisiniz, çünkü alan adınız nasıl çalıştığıyla değil, yalnızca bir arama soyut kavramıyla ilgilidir.

Önemli olmayan tüm şeyleri çıkardıktan sonra, etki alanı modelinin gerçekten anemic olduğunu görürseniz, bu DDD'nin basitçe Projeniz için yanlış paradigma.

Bazı alanlar gerçekten are anemik. Sosyal yer imi uygulamalarından bahsetmek için gerçekten bir "alan adı" yoktur; tüm nesneleriniz temelde işlevselliği olmayan verilerdir. Bir Satış ve CRM sistemi ise oldukça ağır bir alana sahiptir; Bir Rate varlık yüklediğinizde, o zaman sipariş miktarına uygulamak ve çözmesini sağlamak gibi bir şeyler yapın bu oranla makul bir beklenti vardır. Toplu indirimler ve promosyon kodları ve tüm bu eğlenceli şeyler.

Yalnızca verileri tutan etki alanı nesneleri genellikle do anemik bir etki alanı modeliniz olduğu anlamına gelir, ancak bu zorunlu olarak kötü bir tasarım oluşturduğunuz anlamına gelir - sadece alan adının kendisinin anemik olduğu ve farklı bir metodoloji kullanmanız gerektiği anlamına gelebilir.

67
Aaronaught

Yetki. Etki alanı nesnesi erişim kontrol kurallarını korumaktan sorumluysa

Hayır. Yetkilendirme kendi başına bir endişe kaynağıdır. İzin eksikliğinden dolayı geçerli olmayacak komutlar, alan adından önce mümkün olduğunca erken reddedilmelidir - bu, genellikle oluşturmak için bir potansiyel komutunun yetkisini kontrol etmek isteyeceğimiz anlamına gelir. (kullanıcıya düzenleme seçeneğini göstermemek için).

Yetkilendirme, etki alanı modelinden ayrı olarak bileşenlendiğinde yetkilendirme stratejilerini katmanlar arasında (kullanıcı arayüzünde ve daha sonra bir hizmet veya komut işleyicisinde) paylaşmak daha kolaydır.

Karşılaşılabilecek zor bir kısım, bir komutun yalnızca kullanıcı rollerine değil, aynı zamanda iş verilerine/kurallarına da dayalı olarak izin verilebileceği veya verilmeyeceği bağlamsal yetkilendirmedir.

Doğrulama. Yukarıdaki tartışma aynı doğrulama ile ilgilidir.

Ben de hayır diyorum, etki alanında değil (çoğunlukla). Doğrulama farklı bağlamlarda gerçekleşir ve doğrulama kuralları genellikle bağlamlar arasında farklılık gösterir. Bir küme tarafından toplanan veriler düşünüldüğünde, nadiren basit, mutlak bir geçerli veya geçersiz duygusu vardır.

Ayrıca, yetkilendirme gibi, katmanlarda doğrulama mantığını kullanırız - kullanıcı arayüzünde, hizmet veya komut işleyicisinde vb. Yine, ayrı bir bileşense doğrulama ile DRY) doğrulamak daha kolaydır. Pratik bir noktadan itibaren, doğrulama (özellikle çerçeveler kullanılırken) aksi halde kapsüllenmesi gereken verileri ortaya çıkarmayı gerektirir ve genellikle alanlara ve özelliklere özel niteliklerin eklenmesini gerektirir. Bunların etki alanı modellerimden başka sınıflarda olmasını tercih ederim.

Varlıklarımın içine bir doğrulama çerçevesi için gereksinimleri zorlamaya çalışmak yerine, birkaç benzer sınıftaki bazı özellikleri çoğaltmayı tercih ederim. Bu kaçınılmaz olarak varlık sınıflarını karıştırıyor.

Nesne Oluşturma. Fabrika sınıfına karşı fabrika yöntemlerine karşı 'yeni' bir örnek.

Bir dolaylı katman kullanıyorum. Daha yeni projelerimde, bu bir şey oluşturmak için bir komut + işleyicisi, yani CreateNewAccountCommand. Alternatifler her zaman bir fabrika kullanmak olabilir (her ne kadar bir varlık işleminin geri kalanı fabrika sınıfından ayrı bir hizmet sınıfına maruz kalırsa garip olabilir).

Bununla birlikte, genel olarak, nesne oluşturma için tasarım seçenekleriyle daha esnek olmaya çalışıyorum. new kolay ve tanıdık ama her zaman yeterli değil. Burada yargıyı kullanmak ve bir sistemin farklı bölümlerinin gerektiğinde farklı stratejiler kullanmasına izin vermek önemlidir.

Sebat. ... neden etki alanı nesnemizde bir Kaydetme yöntemi yok

Bu nadiren iyi bir fikirdir; Bence bunu destekleyecek çok sayıda paylaşılan deneyim var.

Toplam köküm için bir IAuthorizationService, IValidator, IFactory ve IRepository ile karşılaşırsam, geriye ne kaldı? Sınıfın anemik olmayan bir etki alanı nesnesi olarak değerlendirilecek nesnenin durumunu Taslak'tan Yayınlanmış olarak değiştiren bir Yayınlama yöntemine sahip olmak ???

Belki de bir etki alanı modeli, uygulamanızın bu bölümü için doğru seçim değildir.

6
quentin-starin

Tamam, işte benim için. Bunu önceden söyleyerek önümden çıkaracağım:

  • Erken optimizasyon (ve tasarımı içerir) genellikle sorunlara neden olabilir.

  • IANMF (Ben Martin Fowler değilim);)

  • Kirli küçük bir sır, küçük boyutlu projelerde (muhtemelen orta büyüklükteki projelerde bile), yaklaşımınızın tutarlılığının önemli olacağıdır.

Yetkilendirme

Benim için Kimlik Doğrulama ve Yetkilendirme her zaman kesişen bir konudur. Mutlu küçük Java dünyamda, bu Bahar güvenliğine veya Apache Shiro çerçevesine delege edilir.

Validation Benim için doğrulama, nesnenin ne olduğunu tanımladığını gördüğüm için nesnenin bir parçası.

örneğin. Bir Araba nesnesinin 4 tekerlekleri vardır (Tamam bazı garip istisnalar vardır, ancak şimdilik garip 3 tekerlekli Arabayı görmezden gelelim). Bir Araba 4 (benim dünyamda) olmadığı sürece geçerli değildir, bu nedenle doğrulama bir Araba tanımının bir parçasıdır. Bu, yardımcı bir doğrulama sınıfına sahip olamayacağınız anlamına gelmez.

Happy Java dünyasında Bean doğrulama çerçevelerini kullanıyorum ve Bean alanlarımın çoğunda basit ek açıklamalar kullanıyorum. Hangi katmanda olursanız olun nesnenizi doğrulamak kolaydır.

Nesne Oluşturma

Fabrika derslerini dikkatle görüyorum. Çok sık xyxFactoryFactory sınıfını gördüm;)

Bağımlılık Enjeksiyonunun garanti edildiği bir duruma gelene kadar bir new nesnesi oluşturma eğilimindeyim (ve bir TDD yaklaşımını izlemeye çalıştığımdan beri, bu daha sık gelmiyor).

Mutlu Java benim dünyamda giderek Guice, ama Bahar hala burada Kral.

dayanıklılık

Yani bu daire ve kavşaklarda devam eden bir tartışma ve ben her zaman bu konuda iki aklımdayım.

Bazıları, nesneye 'saf' bir şekilde bakarsanız, kalıcılığın temel bir özellik olmadığını, sadece dışarıdan bir endişe olduğunu söylüyor.

Diğerleri, etki alanı nesnelerinizin dolaylı olarak 'kalıcı özellikli' bir arabirim uyguladığı görüşüne sahiptir (evet, burada esnediğimi biliyorum). Bu nedenle, üzerinde çeşitli save, delete etc yöntemlerinin olması iyi olur. Bu pragmatik bir yaklaşım olarak görülür ve birçok ORM teknolojisi (mutlu benim JPA Java dünya) nesnelerle bu şekilde ilgilenir.

Kesişen bir güvenlik endişesinden, nesnede kaydet/güncelle/sil yöntemini çağıran hizmette düzenleme/silme/ekleme/ne olursa olsun izinlerin doğru ayarlandığından emin olun. Gerçekten paranoyak olsam bile, etki alanı nesnesinin kendisinin izinlerini bile ayarlayabilirim.

HTH!

4
Martijn Verburg

Jimmy Nilsson DDD ile ilgili kitabında bu konuya değiniyor. Anemik bir modelle başladı, daha sonraki bir projede anemik olmayan modellere gitti ve sonunda anemik modellere yerleşti. Onun mantığı, anemik modellerin farklı iş mantığına sahip birden fazla hizmette yeniden kullanılabilmesiydi.

Takas, keşif yeteneğinin olmamasıdır. Anemik modelleriniz üzerinde çalışmak için kullanabileceğiniz yöntemler, başka bir yerde bulunan bir dizi hizmete yayılmıştır.

2
Todd Smith

Bu soru uzun zaman önce soruldu, ancak Etki Alanına Dayalı Tasarım ile etiketlendi. Sorunun kendisinin tüm uygulamanın temel bir yanlış anlaşılmasını içerdiğini ve kabul edilen cevap da dahil olmak üzere cevapların temel bir yanlış anlaşılmayı sürdürdüğünü düşünüyorum.

DDD mimarisinde "etki alanı modeli" yoktur.

Yetkilendirmeyi örnek olarak ele alalım. Sizden bir soru düşünmenizi istiyorum: İki farklı kullanıcının sisteminizde kimliğini doğruladığını düşünün. Bir kullanıcının belirli bir Varlığı değiştirme izni vardır, ancak diğeri değiştirmez. Neden olmasın?

Basit ve özlü örneklerden nefret ediyorum çünkü çoğu zaman aydınlandıklarından daha fazla kafa karıştırıyorlar. Ancak iki farklı alanımız olduğunu varsayalım. Birincisi, bir pazarlama ajansı için bir CMS platformudur. Bu ajansın, kopya içerik yazarları ve grafik sanatçıları tarafından yönetilmesi gereken çevrimiçi içeriğe sahip birçok müşterisi var. İçerik, blog gönderilerini ve farklı müşteriler için açılış sayfalarını içerir.

Diğer alan ise bir ayakkabı şirketi için stok yönetimi. Sistem, Fransa'daki üreticiden, ABD kıtasındaki dağıtım merkezlerine, yerel pazarlardaki perakende mağazalarına ve son olarak ayakkabıları perakende olarak satın alan müşteriye ulaştığında envanteri yönetir.

Yetkilendirme kurallarının her iki şirket için de aynı olduğunu düşünüyorsanız, evet bu alanın dışındaki bir hizmet için iyi bir aday olacaktır. Ancak Yetkilendirme kurallarının aynı olduğundan şüpheliyim. Kullanıcıların arkasındaki kavramlar bile farklı olurdu. Kesinlikle dil farklı olurdu. Pazarlama ajansı muhtemelen posta yazarı ve varlık sahibi gibi rollere sahipken, ayakkabı şirketi muhtemelen nakliye memuru veya depo yöneticisi veya mağaza yöneticisi gibi rollere sahiptir.

Bu kavramlar, muhtemelen etki alanında modellenmesi gereken kendileriyle ilişkili her türlü izin kuralına sahiptir. Ancak bu, aynı uygulama içinde bile aynı modelin bir parçası oldukları anlamına gelmez. Çünkü farklı Sınırlı Bağlamlar olduğunu unutmayın.

Bu nedenle, Yetkilendirme bağlamındaki anemik olmayan bir alan modelinin, hangi reklamları tıkladıklarına bağlı olarak ayakkabı gönderilerini düşük envanter veya site ziyaretçisi olan mağazalara uygun açılış sayfasına yönlendirmek bağlamından farklı olduğu düşünülebilir.

Kendinizi anemik etki alanı modelleriyle bulursanız, kod yazmaya başlamadan önce belki de bağlam eşlemesine daha fazla zaman harcamanız gerekir.

2
RibaldEddie