Etki Alanına Dayalı Tasarım ve Etki Alanları Arası etkileşim


10

Ben göreceli bir DDD acemi değilim, ama kaynatmak ve bilgimi damıtmak için ellerimi alabilir her şeyi ve her şeyi okuyorum.

Bu DDD sorusuyla karşılaştım ve cevaplardan biri beni meraklandırdı.

DDD Sınırlı Bağlamlar ve Etki Alanları?

Yanıtlardan birinde poster, ürünlerin en az 2 alanda bulunduğu bir e-ticaret sistemi örneğini veriyor:

1) Ürün Kataloğu 2) Envanter Yönetimi

Tamam, hepsi mantıklı, yani e-ticaret ön uçunuzda ürün bilgilerini görüntülemekle ilgileniyorsunuz ve envanter yönetimiyle ilgilenmiyorsunuz.

FAKAT. Web sayfasında envanter seviyesini görüntülemek isteyebilirsiniz veya stokta envanterin baskı sayısını görüntülemek isteyebilirsiniz (envanterinizin kitaplar, dergiler vb. Olduğunu hayal edin). Bu bilgiler Envanter alan adından gelir.

Peki, bunu nasıl halledersin? Yapar mısın

a) Hem Ürün etki alanını hem de Envanter etki alanı toplamlarını yüklensin mi? b) Stoktaki sayı ve stok baskısı için Ürün alan adı varlığınızdaki bazı özellikleri tutar ve ardından Envanter varlığı güncellendiğinde bunları güncellemek için Alan Adı Etkinlikleri'ni kullanır mısınız?

Son bir soru. Etki alanının kalıcılığını unutmak / görmezden gelmek ve sadece etki alanı hakkında düşünmek istediğimizi biliyorum. Ancak sadece bunu düşünmek için, yukarıdaki örnekte, ürün kataloğu ve ürün envanteri için potansiyel olarak 2 DB tablosu elde edeceğiz. Şimdi, bunlarda aynı ürünle aynı tanımlayıcıyı mı kullanıyoruz? Veya veriler için 1 tablo ve 1 tablo satırı kullanabilir ve ilgili verileri toplu özelliklerle eşleştirebilir miyiz?

Yanıtlar:


8

Web sayfasında envanter seviyesini görüntülemek isteyebilirsiniz veya stokta envanterin baskı sayısını görüntülemek isteyebilirsiniz (envanterinizin kitaplar, dergiler vb. Olduğunu hayal edin). Bu bilgiler Envanter alan adından gelir.

Bu noktada dikkat edilmesi gereken en önemli şey, bir görünümden bahsetmenizdir, yani eski verileri kullanmanın kabul edilebilir olduğunu söylemektedir.

Bununla birlikte, toplu işlerle (değişikliklerin işletme değişmezini ihlal etmesini önlemekle sorumlu olan) değil, toplamın durumunun yakın zamanda bir kopyasının bir temsiliyle etkileşime girmeniz gerekmez.

Yani normalde ne beklenir Ürün Kataloğu karşı çalıştırmak bir sorgu ve başka bir envanter karşı çalıştırmak ve görünümü desteklemek için gereken DTO içine iki oluşturmak için bir şey.

Hem Ürün etki alanı hem de Envanter etki alanı toplamları yüklensin mi?

Yani bu yakın . Agregaları yüklememiz gerekmez, çünkü hiçbir şeyi değiştirmeyeceğiz. Ama onların devletlerine ihtiyacımız var; böylece yükleyebiliriz. Bununla birlikte, normalde iki alan adının farklı süreçlerde çalışmasını beklerim. Bu nedenle ikisini de çağırıyoruz, ikisini birden yüklemiyoruz.

Stoktaki sayı ve stok baskısı için Ürün alan adı varlığınızdaki bazı özellikleri tutar ve ardından Envanter varlığı güncellendiğinde bunları güncellemek için Alan Adı Olayları'nı kullanır mısınız?

"Akarsuları geçmeyin. Kötü olurdu."

Etki alanı bağlamlarında bilgileri koordine etmek için olayları kullanma: harika bir fikir. Bir alana ait kavramları başka bir alana itmek: daha fazlası hariç, harika bir fikrin tersi.

Etki alanlarını temiz tutmak istiyorsunuz. Uygulamalar etkileşim sahaları ile o kadar önemli değil. Örneğin, Envanter uygulamasının bir görünüme eklemek üzere ürüne özgü bazı kavramları sorgulamak için ürün uygulamasındaki bir hizmeti çağırması mantıklıdır. Ya da tam tersi.

Tek bir uygulamanın tek bir etki alanı ile sınırlı olması için herhangi bir neden bilmiyorum. Tek bir hakikat kaynağı olduğu sürece, işlemleri istediğiniz gibi dağıtabilirsiniz.

Ancak sadece bunu düşünmek için, yukarıdaki örnekte, ürün kataloğu ve ürün envanteri için potansiyel olarak 2 DB tablosu elde edeceğiz. Şimdi, bunlarda aynı ürünle aynı tanımlayıcıyı mı kullanıyoruz?

Bu kolay bir yol olurdu. Daha büyük terimlerle, aynı tanımlayıcıyı kullanırsınız çünkü gerçek dünya varlığı aynıdır; iki farklı sınırlı bağlam modeli bu varlığı farklı şekilde gösterir, ancak model gerçek dünya varlığı değildir.

Bu işe yaramadığında, boşluğu kapatmak için bazı sorgulara ihtiyacınız olacaktır. Bence bunun en yaygın varyasyonu, yeni varlığın eski varlığın kimliğini korumasıdır. Bunu tek bir BC içinde de görürsünüz: başvuru sahipleri onaylandığında müşteri olurlar. Bu farklı bir kümedir (bir müşteriyle ilişkili devlet, başvuranınkinden farklı bir değişmeze tabidir); kalıcılık katmanınız olay akışlarını kullanıyorsa, yeni toplama akışının farklı bir tanımlayıcıya ihtiyacı olacaktır. Yani bir yerlerde “bu başvuran bu müşteri oldu” diyen bir miktar devlet olacak.

Veya veriler için 1 tablo ve 1 tablo satırı kullanabilir ve ilgili verileri toplu özelliklerle eşleştirebilir miyiz?

YIKES! Hayır, yapma. Herhangi bir ticari neden olmadan işlem çekişmesi ekliyorsunuz.


Bunu bir cevap olarak işaretledim, ayrıca bir görünümde görüntülenecek verilerin okunmasının kümelerin yüklenmesini gerektirmediğini belirten @guillaume'e de kredi verdim. Bu kadar ayrıntılı bir cevap için teşekkürler. "Geleneksel" veri modeli ilk yaklaşımından gelince, kalıcılık katmanını unutmaya ve etki alanı diline odaklanmaya zorlandım. Tam olarak aldığımı düşündüğümde, anlayışımı ayıran başka bir makale okudum.
PendorPaul

Ben sadece bağlamlar arasındaki bazı verileri çoğaltmak için Domain Olaylar kullanarak detaylar msdn.microsoft.com/en-us/magazine/dn802601.aspx bu makaleyi okudum . Örnek olarak, müşteri hizmetleri ile sipariş işleme sistemi arasında bir müşteri listesi paylaşılmaktadır. Bu, sipariş sisteminde müşteri verilerini çoğaltır ve verileri senkronize etmek için Etkinlikler'i kullanır. Bu, burada cevapladığımız şeyin karşısında uçuyor. Kesinlikle bağlı örnekte sipariş bağlamı sadece bir müşteri kimliği gerektirir ve bu, müşteri hizmeti bağlamına erişimi olan uygulamadan doldurulabilir.
PendorPaul

Burada düşüncelerinizde çok hassas olmak isteyeceksiniz. Sistemler arasında veri kopyalamak, etki alanı modelleri arasında veri kopyalamakla aynı şey değildir. "Salt okunur [mumble]" ifadesini her gördüğünüzde, verilerin söz konusu alana ait olmaması büyük bir ipucudur (uygulama yine de ilgilense bile).
VoiceOfUnreason

Evet, ben de öyle düşünmüştüm. Düşünme süreci kayması, suları çamurlayan makaleler yayınlamadan "uzmanlar" olmadan yeterince zordur. Bugün, BC ve Agrega Köklerimin nerede yattığını anlamaya çalışmak için alanımı gerçekten analiz ederek geçirdim. Ben hemen hemen oradayım ama aynı zamanda modelimi giderken inceleyip yeniden düzenleyebileceğimi de biliyorum. Ben günlerce aşırı analiz cehennem sıkışmış, benim kafamda DDD düz olmadığı için kod korkusu yazmaya başlamak için endişeleniyor. Bence, çatlamak ve kodumu ve modelin doğru olup olmadığını sorgulamaya devam etmek en iyisidir. Oraya geleceğim. Teşekkürler
PendorPaul

Belki yanlış okudum, ancak konuştuğumuza inandığım uygulamaya Olay Tarafından Taşınan Durum Transferi (Olay Tarafından Taşınan Durum Transferi) denir ve özellikle verileri filtrelemeniz ve sayfalandırmanız gereken gösterge tablosu / tablo görünümleri için çok güçlü bir model olabilir hizmetler arasında. Bu panoları çalıştırmak için alan adı etkinliklerinden "projeksiyonlar" (temelde görünümler) oluşturabilirsiniz. Daha önce oldukça başarılı bir şekilde kullandım. Doğru senaryoda çok güçlü bir araç olabilir. Burada daha önemli olan IMHO, bu projeksiyonların etki alanı modellerini temsil etmediğini ve iş mantığını içermemesi gerektiğini fark etmenizdir.
Ürdün

3

Bence sorunuz gerçekten 2 dikey seçenek kümesi gerektiriyor -

  • İki nesne yüklüyor ve verilerini bir arada sunuyor musunuz veya istediğiniz her şeyi içeren 1 nesne yüklüyor musunuz?

  • Bir şeyleri veya başka bir şeyi görüntülemek için toplamalar kullanıyor musunuz?

CQRS yaklaşımına inanıyorsanız, toplamaların okumalar için en iyi bahis olmayabileceği ortaya çıkıyor. Bir toplama her yüklediğinizde, verilerini görüntülemek veya değiştirmek için sisteminize eşzamanlılık ve çekişme eklersiniz. Ayrıca, agregalar, görüntüleme için uyarlanmış geçici okuma modelleri kullandığınızdan daha potansiyel olarak daha hantal ve daha yavaş yüklenir.

A) 'dan gelen çözüm bu tuzakların çoğuna tabi görünüyor. Seçenek b) geçerli olabilir, ancak toplamı InventoryManagementmutasyona uğratırken değişmezleri zorlamak için BC'den gelen veriler gerektiğinde kullanırım Product. Bir topluluğun, değişiklik üzerine iş kurallarını kontrol etmek için gerekli tüm verileri içermesi daha iyidir, ancak okuma tarafında herhangi bir yere oturabilirler.

Verilerle ilgili olarak ortak bir öneri Sınırlı Bağlamlara kendi veritabanlarını vermektir (konuşlandırılabilirlik ve SoC nedenleriyle). İki BC arasındaki ürünleri eşleştirmek istiyorsanız muhtemelen aynı tanımlayıcıları kullanmanız gerekecektir.

BC çapraz etkileşimleri hakkında ayrıca /programming/16713041/communicating-between-two-bounded-contexts-in-ddd adresine de göz atmak isteyebilirsiniz.


1
Tamam, bu yardımcı olur. Esasen, değişmezlerimizin tutarlı olmasını ve verilerimizin geçerli olmasını ve gerçekleştirmek istediğimiz işlemlerin topluluğumuz ya da M.Ö. Bu verileri okumak ve görüntülemek söz konusu olduğunda, tüm agregalar / BC hidratlanmadan bunları ayrı ve hafif olarak ele alabiliriz. Sonuçta, yaptığımız tek şey verileri bir raporda veya ekranda görüntülemek olduğunda Toplamı neden yüklememiz gerekiyor? Bu çok mantıklı. Teşekkürler.
PendorPaul

CQRS gerçekten parlıyor. Sadece bir SQL sorgusu yapabilir, tablolara katılabilir ve belirli bir görünüm için uyarlanmış sorguyu döndürebilirsiniz. Ayrıca, repo'nuzu sorgu yöntemi karmaşasından temizler. Ayrıca, Esnek Arama gibi hizmetteki verileri bile çoğaltabilir ve buna karşı sorgulayabilirsiniz.
17:

1

DDD, iş mantığının karmaşık olduğu uygulamalar içindir. "bir şey yazdır" karmaşık bir iş mantığı değildir. Aslında hiç de bir iş mantığı değil.

Bir bağlamdaki iş mantığının, bazı kullanım durumlarını doğru bir şekilde işlemek için bazı bilgilere ihtiyacı varsa, bu bilgi bu bağlamın bir parçasıdır. Dolayısıyla, sınırlı bir bağlamın farklı sınırlı bağlamda mevcut bilgilere ihtiyaç duyabileceği fikri mantıklı değildir, çünkü sınırlı bağlam ihtiyaç duyduğu tüm bilgilere sahiptir.


Tamam, Amazon gibi bir şey alın, bu karmaşık iş mantığına sahip karmaşık bir sistem. Katalog yönetimi ve envanter yönetimi vardır. Ürün adını, açıklamasını, türünü, koşulunu vb. Kastederek kataloğu yönetmek için envanter toplamlarına ihtiyaç duymazlar. Ancak, mağaza ön sayfasında stokta bulunan öğe sayısını gösterirler. Ürün Kataloğu Yönetimi ve Ürün Envanteri alanlarınızı ayırmak istediğiniz ancak ürün sayfanızda envanter hakkında bazı bilgiler görüntülemeniz gereken bu senaryoda, bunu nasıl yapıyorsunuz?
PendorPaul

Ürün Katalogu etki alanının, ürün kataloğunu yönetmek için gereken tüm bilgilere sahip olduğunu söylüyorum. Envanter alanı, envanteri yönetmek için ihtiyaç duyduğu tüm bilgilere sahiptir. Ancak, bir kullanıcıya bazı bilgiler görüntülemek istediğimde ve bu veriler 2 alandan geliyorsa, bunu nerede yapacağım. Kullanıcı arayüzüme her iki alan adını da yükleyip göstermek istediğim özellikleri mi bağlarım? Yoksa, kullanıcı arayüzüm için ihtiyacım olan verileri içeren anonim bir tür veya DTO döndürdüğüm bir raporlama / okuma mekanizmam var mı?
PendorPaul

11 ay önceki bu eski yorumlara bakmak komik, ama bir ömür gibi görünüyor. Okuma ve yazma yönü hakkında tamamen doğru Euphoric. Üzerinde çalıştığım uygulama, anlayışım geliştikçe biraz gelişti. Şimdi Jimmy Bogards Mediatr aracılığıyla CQRS yöntemlerini kullanıyorum. Toplamalarla etkileşime giren komutlara sahip olmanın esnekliği, ancak daha sonra görüntüleme için ihtiyacım olanı geri getirmek için sorguları ve sorgu işleyicilerini kullanmak inanılmaz. Bunu, QueryHandlers'ı çağıran Görünümlere sarın ve ayırma işlemi bununla iyidir. Teşekkürler
PendorPaul

@PendorPaul, sanırım 11 (şimdi 13) ay önce bulunduğun yerdeyim. Seni şu an bulunduğun yere ne götürdü?
Greg Bell

1
@GregBell Zihniyet değişikliğini zorlamanız gerekir. "Bir veritabanı tasarlama, bir veri katmanı oluşturma, bazı iş mantığı oluşturma ... vb." Ve tüm kuşatıcı varlıkları yaratmaya odaklandım. yani fiyatlandırma, açıklama, envanter, stok konum .... her şeyi ele bir e-ticaret sitesinde bir "Ürün" .... ama bu son derece karmaşık hale gelir. Sınırlı bağlam yaklaşımı, Envanter bağlamında "Ürün" yalnızca envanter yönetimi için bilgi ve davranışlar içerdiği anlamına gelir. Açıklama ve resimler, içerik bağlamında yönetilir, fiyatlandırma bağlamında fiyatlandırılır.
PendorPaul

1

Benim bakış açımdan "Ürün" ün farklı tanımları vardır - her sınırlayıcı bağlam kendi "ürün" -alan tanımına sahiptir:

  • İçerik-Yönetim-Sınırlayıcı-Bağlamda bir ürünün bir resmi ve bir açıklama metni vardır.
  • Envanter Bağlama-Bağlamında bir ürünün stok miktarları, ürün satıcısı, ürün ne zaman mevcut olacağı tahminleri vardır
  • Fiyat-Caculation-Sınırlayıcı-Bağlamda bir ürün miktar başına ne kadar mal olabilir kuralları vardır.

Bunların üzerine, kendi ürün tanımlamasıyla (diğer Sınırlayıcı Bağlamların ürün alanlarının ilgili bir kombinasyonu) ek bir Dükkan Bağlayıcı-Bağlam ekleyeceğim .

Bir Mağaza Ürününde içerik ve kullanılabilirlikten "Envanter" den "görüntü ve açıklama metni" olur, ancak envanterden "ürün satıcısı" olmaz.

Bu ek Dükkan Bağlayıcı-Bağlam Bağlayıcı Bağlam İçeriğine, Envanterine, Fiyata bağlıdır


Peki, bu Shop-Product BC'yi nasıl yaratıyorsunuz? Bu bağlamda, BC Ürünü ve Envanterine referansınız var ve bir Mağaza-Ürün BC'si yüklediğinizde bunları kalıcılık deponuzdan nemlendiriyor ve daha sonra bu BC'lerden istediğiniz özellikleri StoreProduct özellikleriniz aracılığıyla mı sunuyorsunuz? Bu makaleyi aslında düşündüğüm şeylerin arasında, BC olaylarını çapraz olarak buldum, ancak yukarıdaki @ guillaume13, görüntüleme amaçları için BC'den kaçınabileceğimi ve sadece benim görüşüm için ihtiyacım olan verileri geri çekebileceğimi belirtti. msdn.microsoft.com/en-us/magazine/dn802601.aspx
PendorPaul
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.