Agrega sınırları nasıl tasarlanır?


10

Bir uygulamaya e-ticaret gibi bir şey yazmak istiyorum.

Ve benzer uygulamalarda ürünlerin farklı özelliklere ve özelliklere sahip olabileceğini biliyorsunuz. Böyle bir fırsatı simüle etmek için aşağıdaki alan modeli varlıklarını oluşturdum:

Kategori - bu "elektronik> сomputers" gibi bir şey yani ürün türleri. Kategoriler, özelliklerin bir listesini içerir (Liste <Özellik>).

Mülkiyet - adını içeren bağımsız bir varlık, ölçü birimleri, veri türü. Örneğin "ad", "ağırlık", "ekran boyutu". Aynı mülkün farklı ürünleri olabilir.

Ürün - sadece özelliklerle ilgili değerlerin listesini ve adını içerir. Değer, özelliğin yalnızca değer alanını ve alan kimliğini içeren bir nesnedir.

Başlangıçta Kategori'yi bu şemada tek bir toplama gibi yapmaya karar verdim çünkü örneğin yeni ürün eklediğimde, geçerli kategoriyle ilgili özellikler ( category.AddNewProduct (ürün) ) dahil olmak üzere mevcut kategoriyle ilgili tüm verileri bilmem gerekiyor . Ancak, herhangi bir kategoriye ait olmayan yeni bir mülk eklemem gerektiğinde ne yapmalıyım. Örneğin, bu kategoriyi yapamıyorum.AddNewProperty (özellik) , özelliği belirli bir kategoriye eklediğimizi açıkça söylüyor.

Tamam sonraki adım ayrı Mülkiyet ayrı bir toplama karar verdi ama sonra basit varlıkları ile bir liste olacak.

Tabii ki özellik ve iş kuralları listesi içinde tutmak için PropertyAggregate gibi bir şey oluşturabilirim, ancak bir ürün eklediğimde, kategorinin içinde değişmeyenleri kontrol etmek için bu kategoriye ait özelliklerin tüm listesine sahip olmalıyım. Ama aynı zamanda, diğer agregalardaki toplamaların içindeki bağlantıların kötü bir uygulama olduğunun da farkındayım.

Bu iş vakasını tasarlamanın seçenekleri nelerdir?


Bir kategori, mülk ve ürüne daha eksiksiz bir örnek verebilir misiniz? Elektronik veya bilgisayar bir kategori, iPhone X bir ürün örneği ve bir özellik tam olarak ne olurdu? 11 "inç ekran?
Neil

neredeyse haklısın. Bazı açıklamalar ekledim
cephei

Görünüşe göre toplu tasarıma yalnızca "veri taşıyıcısı" perspektifinden bakıyorsunuz. Ayrıca, işlemsel yönleri, işbirliği / eşzamanlı erişim, meydana gelen olaylar, durum geçişleri, vb. Dikkate alınarak, uygulamanızın kullanım durumlarını da düşünmek isteyebilirsiniz
guillaume31

Yanıtlar:


7

DDD perspektifte Category, Productve Propertyvarlıklardır: kendi kimliğe sahip nesnelere tüm karşılık gelmektedir.

1.Seçenek: Orijinal tasarımınız

Sen yapılmış Categorytek bir cihaz kök. Bir tarafta, bu mantıklıdır, çünkü agrega, nesneleri değiştirildiğinde tutarlılığı sağlamalı ve Productaşağıdakilerden Propertiesbirine sahip olmalıdır Category:

resim açıklamasını buraya girin

Ancak diğer tarafta, tek toplama, tüm nesnelerinin onlara sahip olan bir kökle ilişkili olduğu ve tüm dış referansların bu toplu kök yoluyla yapılması gerektiği anlamına gelir. Bu şu anlama gelir:

  • bir özel Productbir ve sadece birine aittir Category. Eğer Categorysilinirse, onun da silinir Products.
  • belirli Propertybir ve sadece birine aittir Category. Aksi takdirde, "TV ekranları" ve "Bilgisayar monitörleri" iki kategoriyse, "TV ekranları: boyut" ve "Bilgisayar monitörleri: boyut" iki farklı özellik olacaktır.

İkinci nokta anlatımınıza uymuyor: " Ama sadece Propertyherhangi bir kategoriye ait olmayan yeni bir şey eklemem gerektiğinde ne yapmalıyım ". Ve bunun Propertiesfarklı bir şekilde kullanılabileceği açık değil Categories.

2. Seçenek: Toplamın dışındaki mülk

Bir Eğer Propertybağımsız var Categories, bu agrega dışında olmalıdır. Ve aynı şey Propertiesarasında paylaşmak istiyorsanız Categories(yükseklik, genişlik, boyutlar vb. İçin anlamlıdır). Bu kesinlikle doğru gibi görünüyor.

Sonuç, Propertytopluluğa ait olan ve bu nesneye ait olan şeyler üzerindedir: topluluğun iç kısmından konumuna gidebilirken, Propertyartık doğrudan Propertya'dan karşılık gelen değerlere gitmenize izin verilmez . Bu gezinme kısıtlaması bir UML diyagramında gösterilebilir:

resim açıklamasını buraya girin

Not Bu tasarım var engellemez etmediğini List<Property>in Categoryanlamsal bir referans (örn java) ile: listedeki her referans paylaşılabilir bir atıfta Propertybir depoda nesne.

Bu tasarımla ilgili tek sorun, onu değiştirebilmeniz Propertyveya silebilmenizdir: agrega dışında olduğu için, agrega değişmezlerinin tutarlılığına dikkat edemez. Ama bu bir sorun değil. DDD ilkelerinin ve gerçek dünyanın karmaşıklığının sonucudur. İşte Eric Evans'ın " Domain-Driven Design: Yazılımın Kalbinde Karmaşıklıkla Mücadele " başlıklı kitabında bir alıntı :

AGREGATES'i kapsayan hiçbir kuralın her zaman güncel olması beklenmez. Olay işleme, toplu işleme veya diğer güncelleme mekanizmaları aracılığıyla, diğer bağımlılıklar belirli bir süre içinde çözülebilir. Ancak bir AGREGATE içinde başvurulan değişmezler her işlemin tamamlanmasıyla icra edilecektir.

Bu nedenle evet, a'yı değiştirirseniz Property, bir hizmetin kendisine atıfta bulunan Kategorileri kontrol ettiğinden emin olun.

Seçenek 3: Farklı agregalarda Kategori, Mülk ve Ürün

Sadece Productbir bekarın ait olduğu varsayımının Categorykurulmuş olup olmadığını merak ediyorum :

  • İnternet mağazalarının sık sık Productbirkaçını önerdiğini görüyorum Categories. Örneğin, "Dizüstü Bilgisayarlar Marka X Model Y" yi "Dizüstü Bilgisayarlar" kategorisinde ve "Bilgisayarlar" kategorisinde ve "çok işlevli yazıcı Z" yi "yazıcı", "tarayıcı" ve "faks" kategorisinde bulabilirsiniz.
  • Birinin bir Productilk oluşturması ve daha sonra onu Kategoriler'e ataması ve değerleri doldurması mümkün değil mi?
  • Bir kategoriyi bölmek isterseniz, Ürünlerini gerçekten siler ve ardından yeni kategoriler altında yeniden oluşturur musunuz?

Toplamaları basitleştirmeyecek ve toplamaları kapsayan daha fazla kuralınız olacaktır. Ancak sisteminiz geleceğin çok daha kanıtı olacaktır.


Çok teşekkür ederim, bu çok faydalı bir açıklama. Ama birkaç noktayı açıklığa kavuşturmak istiyorum, ikinci seçenekle başlamak istiyorum ve kim bilir, belki üçüncüye geleceğim. Eğer toplamın Propertysınırlarını Categoryaşarsam, bu Propertykendi içinde bir yığın haline gelen ve bir depoya ihtiyaç duyduğu anlamına mı gelir? O zaman doğruysa nasıl gerekli geçiren etmek List<Property>içine CategoryMesela? Yapıcı aracılığıyla mı? Doğru olacak mı? Ve henüz oluşturulmamış Propertybir kimliklerin listesini nasıl bulabilirim Category?
cephei

Kısaca @zetetic: evet, bağımsız bir Mülkiyet deposuna ihtiyacınız olacak. Mevcut Özellikler listesini Kategori fabrikasına iletirsiniz veya boş Kategoriler oluşturur ve listeyi bir addProperty yöntemiyle doldurursunuz. Buna karşılık soru: "zorunlu" ve "isteğe bağlı" Özelliklere sahip olmak istediğinizi ve zorunlu özellik kategoriye bağlı olduğunu düşünün. Bu işi nasıl halledersin ?
Christophe

aklınıza gelen ilk şey, özel bir varlık yaratabileceğim Featureve bu sorunun yalnızca Product. ve bu varlık aramaya katılmayacak. ne dersin ?
cephei

@zetetic neden olmasın! Değerleri şu anda üründe oldukları gibi bırakmıştım ve özelliği kategoriyle ilişkilendirirdim. Bir kategoride n özelliği vardır (toplamının bir parçası), bir Özellik m Özelliklerini tanımlar (ancak bağlantı Kategori-> özelliğiyle gider). Daha sonra, çoktan çoğa ilişkiyi daha yönetilebilir öğelere ayırarak, toplam sınırı açıklığa kavuşturdunuz. Son olarak depo enjeksiyonu hakkında: kimlikle diğer toplamalara başvurursanız bu gerekli değildir (bu makaleyi okuyun informit.com/articles/article.aspx?p=2020371&seqNum=4 )
Christophe

5

Gördüğüm gibi, bunu iki yoldan biriyle çözebilirsiniz:

Kategori özel bir ürün türüdür

Bu, veritabanınızdaki herhangi bir ürün için, aynı tablo ürününe işaret eden yabancı bir anahtar içerdiği anlamına gelir. Bir ürün, yalnızca yabancı anahtarı söz konusu ürünün kimliğine eşit hiçbir ürün yoksa bir üründür. Başka bir deyişle, altında ürün yoksa, bir üründür.

Bu işleri kolaylaştırır. Mülkler için ürünler bire çok ilişkisine sahip olur ve bu nedenle kategorileriniz de ürün oldukları için bire çok ilişkisine sahiptir. Bir kategoriye özellik eklemek, programınızdaki bir ürüne özellik eklemek kadar kolay olacaktır. Tüm özelliklerin yüklenmesi, ürünün özelliklerinin, ilişkili kategori ürününün özellikleriyle birleştirilmesi ve siz üst öğe içermeyen bir kategori ürününe ulaşıncaya kadar devam etmesi anlamına gelir.

E-ticaret uygulamanızın bu ayrımı yapması gerekir, ancak yine de bir kategorideki ürünleri yükleyecekseniz, bir kategori veya ürünle ilgilenip ilgilenmediğinizi bilmek bir performans kaybı değildir. Ayrıca, her ürün (kategori) fazladan iş yapmadan bir alt ürün listesine açılacağı için ağaç modasında ürün seviyesine arama yapmayı da iyi bir şekilde ödünç vermektedir.

Bunun dezavantajı elbette bir kategori için mantıklı olmayan üründe mevcut ekstra bilgiler üründe garip kullanılmayan alanlar yaratacaktır. Bu çözüm uygulamanızda daha esnek olsa da, biraz daha sezgiseldir.

Çoktan çoğa ilişki

Ürünler artık mülkiyet ile bileşik bir ilişki içinde değil. Bu ikisini birbirine bağlayan hem ürün tablosu hem de özellik tablosunun yabancı anahtarlarıyla bir ProductProperty tablosu oluşturursunuz. Benzer şekilde, özellik tablosu ile çoktan çoğa ilişkisine sahip bir kategori tablonuz ve hem kategori tablosu hem de özellik tablosunun yabancı anahtarlarına sahip bir CategoryProperty tablosu var.

Ürünün kendisi, kategori ile çoktan bire bir ilişkiye sahip olacak ve iyi bir resmileştirilmiş seçme ifadesi ile hem ürün hem de kategoriyle ilgili benzersiz özelliklerin bir listesini oluşturmanıza izin verecektir.

Veri tabanı açısından, bu kesinlikle daha temiz ve daha esnektir. Sorgunuz doğru şekilde yapılırsa, uygulamanız büyük olasılıkla doğrudan CategoryProperty veya ProductProperty ile uğraşmadan yapabilir. Ancak, kategoriyi veya ürünü mülk sahibi olarak değerlendirmemelisiniz. Programınız içinde kendi varlığı olmalıdır. Bu aynı zamanda söz konusu mülklerin yönetiminin mülkün kendisinin yaratılması, daha sonra iki ayrı adımda bir kategori veya ürünle ilişkilendirilmesi anlamına geleceği anlamına gelir. Kesinlikle ilk çözümden daha fazla iş, ama hiçbir şekilde daha zor.

Buna ek olarak, özelliklerinden herhangi biri başkaları tarafından kullanılıyorsa, kategorinin veya ürünün silinmesi üzerine ek bir kontrol yapmanız gerekir (belirli bir ürünün / kategorinin tüm ilgili özelliklerini güvenli bir şekilde ortadan kaldırabileceğiniz ilk çözümün aksine) .

Sonuç

Profesyonel bir bağlamda, çoktan çoğa yaklaşımı kullanarak üründen ve üründen ekstra mil ve mesafe kategorisine giderdim. Verilerin örtüşmesi olasılığı yoktur ve bir anlamda, bu üçünün her birinin kendi varlığı olarak düşünülmesi daha kolaydır. Ancak, ilk çözüm hiçbir şekilde kötü bir çözüm değildir, çünkü daha basit bir uygulama yazmanıza izin verir. Sadece bir çözümden diğerine geçmeniz gerekebileceğini düşünüyorsanız, ikincisini seçmek muhtemelen sizin yararınıza olacaktır.

İyi şanslar!


Ayrıntılı ve ilginç cevap için teşekkürler! veritabanı düzeyinde zaten ikinci durumda açıkladığınız gibi modelledim, bu kalıba varlık-öznitelik-değer denir, ancak kod düzeyinde, yani toplamların tanımına yapıştım. Çoğu durumda, tüm bu varlıklar birlikte kullanılır. tek bir toplamada birleştirmek mümkündür, ancak mantıken toplamdan dövülen dizinlerin doldurulması gibi durumlar vardır.
cephei
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.