2011-05-24 14 views
11

मेरे पास डीडीडी मॉडल में दो समग्र जड़ों के बीच संबंधों के बीच संबंधों के संबंध में कुछ प्रश्न हैं। नीचे चित्रित ठेठ ग्राहक/ऑर्डर मॉडल का संदर्भ लें।कुल जड़ों के बीच संबंधों और बाधाओं को कैसे लागू करना चाहिए?

enter image description here

पहले, समुच्चय के वास्तविक वस्तु कार्यान्वयन के बीच संदर्भ हमेशा ID मान के माध्यम से किया जाना चाहिए और संदर्भ आपत्ति नहीं? उदाहरण के लिए यदि मुझे ऑर्डर के ग्राहक पर ब्योरा चाहिए तो मुझे ग्राहक आईडी लेना होगा और ग्राहक को प्राप्त करने के लिए ऑर्डर ऑब्जेक्ट को सेट करने के बजाय इसे ग्राहक को सीधे सही करने के लिए आईसीएलएडर रीपोजिटरी में पास करना होगा? मैं उलझन में हूं क्योंकि एक ग्राहक को वापस लौटने से लगता है कि यह मॉडल के खिलाफ लेखन कोड को आसान बना देगा, और अगर मैं एनएचबीनेटनेट जैसे ओआरएम का उपयोग कर रहा हूं तो सेटअप करना बहुत कठिन नहीं है। फिर भी मैं काफी हद तक निश्चित हूं कि यह कुल जड़ों/भंडारों के बीच की सीमाओं का उल्लंघन करेगा।

दूसरा, दो समग्र जड़ों के लिए हटाने के संबंध में कैस्केड को कैसे और कैसे बनाया जाना चाहिए? उदाहरण के लिए, मैं चाहता हूं कि जब कोई ग्राहक हटा दिया जाए तो सभी संबंधित ऑर्डर हटा दिए जाएंगे। ICustomerRepository.DeleteCustomer() विधि IOrderRepostiory को संदर्भित नहीं किया जाना चाहिए? ऐसा लगता है कि समेकित/भंडारों के बीच की सीमाओं को तोड़ दिया जाएगा? क्या मुझे इसके बजाय एक ग्राहक प्रबंधन सेवा है जो ग्राहकों और उनके संबंधित आदेशों को हटाने में संभालती है जो IOrderRepository और ICustomerRepository दोनों का संदर्भ लेंगी? उस स्थिति में मैं कैसे सुनिश्चित कर सकता हूं कि लोग सेवा का उपयोग करना जानते हैं, न कि ग्राहकों को हटाने के लिए भंडार। क्या यह मॉडल को सही ढंग से उपयोग करने के तरीके पर शिक्षित करने के लिए बस नीचे है?

उत्तर

9

सबसे पहले, हमेशा योग मानों के माध्यम से समेकन के बीच संदर्भ होना चाहिए, वास्तविक वास्तविक संदर्भ नहीं?

वास्तव में नहीं - हालांकि कुछ प्रदर्शन कारणों से उस बदलाव को बदल देंगे।

उदाहरण के लिए अगर मैं एक आदेश के ग्राहक पर विवरण चाहते हैं मैं ग्राहक आईडी लेने के लिए और आदेश वस्तु की स्थापना एक ग्राहक सीधे सही वापस जाने के लिए तो बजाय एक ग्राहक पाने के लिए यह एक ICustomerRepository को पारित करने के लिए की आवश्यकता होगी?

आमतौर पर, आप रिश्ते (जैसे।, Customer.Orders या Order.Customer) ट्रेवर्सल के लिए 1 पक्ष मॉडल चाहते हैं। दूसरा उपयुक्त रिपोजिटरी (उदाहरण के लिए, CustomerRepository.GetCustomerFor(Order) या OrderRepository.GetOrdersFor(Customer)) से प्राप्त किया जा सकता है।

क्या इसका मतलब यह नहीं होगा कि ऑर्डर रिपॉजिटरी को ग्राहक बनाने के तरीके के बारे में कुछ जानना होगा? क्या OrderRepository जिम्मेदार होना चाहिए कि परे नहीं होगा के लिए ...

OrderRepository एक ICustomerRepository.FindById(int) उपयोग करने के लिए कैसे पता होगा। आप ICustomerRepository इंजेक्ट कर सकते हैं। कुछ इसके साथ असहज हो सकते हैं, और इसे एक सेवा परत में रखना चुनते हैं - लेकिन मुझे लगता है कि यह अधिक है। कोई विशेष कारण नहीं है कि भंडार एक दूसरे के बारे में नहीं जानते और उपयोग नहीं कर सकते हैं।

मैं उलझन में हूं क्योंकि ग्राहक को वापस लौटने से लगता है कि यह मॉडल के खिलाफ लेखन कोड आसान बना देगा, और अगर मैं एनएचबीनेटनेट जैसे ओआरएम का उपयोग कर रहा हूं तो सेटअप करना बहुत मुश्किल नहीं है। फिर भी मैं काफी हद तक निश्चित हूं कि यह कुल जड़ों/भंडारों के बीच की सीमाओं का उल्लंघन करेगा।

सकल जड़ें अन्य कुल जड़ों के लिए संदर्भ धारण करने के लिए अनुमति दी जाती है। वास्तव में, किसी भी रूट के संदर्भ में कुछ भी रखने की अनुमति है। एक समग्र रूट एक गैर-कुल रूट इकाई का संदर्भ नहीं रख सकती है, जो इसके अंतर्गत नहीं है। ।

जैसे, CustomerOrderLines के लिए एक संदर्भ पकड़ नहीं कर सकते हैं - के बाद से OrderLines ठीक से Order कुल जड़ पर एक इकाई के रूप अंतर्गत आता है।

दूसरा, दो समग्र जड़ों के लिए रिमोट रिलेशनशिप पर कैस्केड कहां और कैसे किया जाना चाहिए?

हैं (और मैं अगर तनाव है, क्योंकि यह एक अजीब आवश्यकता नहीं है) एक उपयोग मामला है कि वास्तव में, यह एक संकेत है कि Customer अपने एकमात्र कुल जड़ होना चाहिए। सबसे वास्तविक दुनिया प्रणालियों में, तथापि, हम नहीं वास्तव में एक Customer कि Order रों संबंधित किया जाता है को नष्ट होगा - हम, उन्हें निष्क्रिय हो सकती हैं किसी मर्ज किए गए Customer, आदि पर ले जाने के उनके Order रों - लेकिन बाहर और बाहर नहीं Order हटाना रों।

कहा जा रहा है, जबकि मैं इसे शुद्ध DDD है, सबसे लोगों का काम पैटर्न की एक इकाई आप Order रों जहां हटा सकते हैं और उसके बाद निम्न में कुछ उदारता की अनुमति देगा नहीं लगता कि Customer (अभी भी विफल हो जाएगा जो अगर Order रों अस्तित्व में)। यदि आप चाहें तो CustomerRepository काम भी कर सकते हैं (हालांकि मैं इसे और अधिक स्पष्ट करना चाहता हूं)। अनाथाश्रम Order एस को बाद में साफ करने के लिए स्वीकार्य है (या नहीं)। उपयोग का मामला यहां सभी अंतर बनाता है।

मैं बजाय एक CustomerManagment सेवा है जो ग्राहकों को हटाने और उनके संबद्ध आदेश जायें जो कि दोनों रूप में उल्लेख एक IOrderRepository और ICustomerRepository संभालती है चाहिए? उस स्थिति में मैं कैसे सुनिश्चित कर सकता हूं कि लोग सेवा का उपयोग करना जानते हैं, न कि ग्राहकों को हटाने के लिए भंडार। क्या यह मॉडल को सही ढंग से उपयोग करने के तरीके पर शिक्षित करने के लिए बस नीचे है?

शायद मैं भंडार से इतनी गहराई से बंधे कुछ के लिए एक सेवा मार्ग नहीं जाऊंगा। यह सुनिश्चित करने के लिए कि एक सेवा का उपयोग कैसे किया जाता है ... आप CustomerRepository पर सार्वजनिक Delete नहीं डालते हैं। या, Customer को हटाने पर Order एस अनाथ छोड़ने पर आप एक त्रुटि फेंक देते हैं।

+0

धन्यवाद! यह वास्तव में बहुत मदद करता है। हालांकि, एक रिश्ते का एक पक्ष मॉडल में जोड़ा गया है जैसा कि आप ऑर्डर के रूप में वर्णन करते हैं। ग्राहक संपत्ति। इसका मतलब यह नहीं होगा कि ऑर्डर रिपोजिटरी को ग्राहक बनाने के तरीके के बारे में कुछ जानना होगा? क्या ऑर्डर रिपोजिटरी के लिए ज़िम्मेदार नहीं होना चाहिए, और इस प्रकार "डेमेटर लॉ" (http://bit.ly/smi5M) को तोड़ना चाहिए। इस प्रश्न का उत्तर (http://bit.ly/iuVq2k) मूल रूप से मुझे लगता है कि आर्ग्रेगेट जड़ों के संदर्भ केवल आईडी के रूप में सहेजे गए हैं और संदर्भ संदर्भ नहीं हैं। –

+0

मेरे पास ऊपर से पूछे गए एक से संबंधित प्रश्न है, मान लीजिए कि रिश्ते के एक तरफ मैं कुछ ग्राहक 'ऑर्डरर्स' जैसा करता हूं, अब आदेश आलसी लोड हो जाएगा, हालांकि निर्भरता के बारे में क्या है जो इस मामले में एक रिपोजिटरी ऑर्डर रिपोजिटरी लोड किया है? उदाहरण के लिए यदि ऑर्डर रिपोजिटरी प्रत्येक ऑर्डर एआर में इवेंटप्लिशर इंजेक्ट करेगी, तो यह इस परिदृश्य में मिस्ड हो जाएगा – Sudarshan

+0

@ सुदर्शन - ग्राहक रिपोजिटरी ऑर्डर इकाई लोड करने के लिए ऑर्डर रेपॉजिटरी का उपयोग कर सकती है (और चाहिए)। इस तरह, आप कस्टमर रिपोजिटरी और ऑर्डर रिपोजिटरी के बीच तर्क को डुप्लिकेट नहीं कर रहे हैं। यदि ऑर्डर एक समग्र रूट भी है, तो ऑर्डर रिपॉजिटरी को सार्वजनिक रूप से सुलभ और FindOrdersByCustomerId विधि आंतरिक होना चाहिए। यदि यह कुल रूट नहीं है, तो इसे केवल ग्राहक पंजीकरण के लिए आंतरिक या निजी होना चाहिए - क्योंकि बाहरी ग्राहकों को गैर-समग्र इकाई का प्रत्यक्ष संदर्भ रखने की अनुमति नहीं है। –

1

एक और विकल्प ऑर्डर और ग्राहक एआरएस, वीओ के बीच संबंध का वर्णन करने वाला वैल्यू ऑब्जेक्ट होगा जिसमें ग्राहक आईडी और अतिरिक्त जानकारी हो सकती है - नाम, पता आदि (क्लाइंटइन्फो या ग्राहक डेटा जैसी कुछ)।

यह है कई फायदे:

  1. आपका ARS decoupled रहे हैं - और अब विभाजित किया जा सकता, इवेंट स्ट्रीम आदि के रूप में जमा
  2. आदेश ARS में आप आमतौर पर जानकारी आप था रखने के लिए की जरूरत ऑर्डर सृजन के समय ग्राहक के बारे में और ग्राहक पर किए गए भविष्य में किए गए किसी भी बदलाव को प्रतिबिंबित नहीं करते हैं।
  3. लगभग सभी मामलों में मूल्य वस्तु में जानकारी पढ़ने के संचालन करने के लिए पर्याप्त होगी (ऑर्डर के साथ ग्राहक जानकारी प्रदर्शित करें)।

किसी ग्राहक के हटाने/निष्क्रिय करने को संभालने के लिए आपको अपनी पसंद का कोई भी व्यवहार चुनने की स्वतंत्रता है। आप DomainEvents का उपयोग कर सकते हैं और एक ग्राहक हटाए गए ईवेंट को प्रकाशित कर सकते हैं जिसके लिए आपके पास एक हैंडलर हो सकता है जो ऑर्डर को किसी संग्रह में ले जाता है, या उन्हें हटा देता है या जो भी आपको चाहिए। आप उस घटना पर एक से अधिक ऑपरेशन भी कर सकते हैं।

यदि किसी भी कारण से डोमेनइवेंट्स आपकी पसंद नहीं हैं तो आप एक सेवा ऑपरेशन के रूप में हटाए गए हटाए गए ऑपरेशन को प्राप्त कर सकते हैं, न कि रिपोजिटरी ऑपरेशन के रूप में और दोनों एआरएस पर संचालन करने के लिए यूओयू का उपयोग करें।

मैंने डीडीडी करने की कोशिश करते समय इस तरह की कई समस्याएं देखी हैं और मुझे लगता है कि समस्याओं का स्रोत यह है कि डेवलपर्स/मॉडलर्स के पास डीबी शर्तों में सोचने की प्रवृत्ति है। आप (हम :)) में अनावश्यकता को हटाने और डोमेन मॉडल को सामान्य करने की प्राकृतिक प्रवृत्ति है। एक बार जब आप इसे प्राप्त कर लेते हैं और अपने मॉडल को विकसित करने और डोमेन के विशेषज्ञों को इसके विकास में शामिल करने की अनुमति देते हैं तो आप देखेंगे कि यह जटिल नहीं है और यह काफी स्वाभाविक है।

अद्यतन: और एक समान VO - OrderInfo केवल आवश्यक जानकारी के साथ, ग्राहक एआर के अंदर रखा जा सकता है अगर जरूरत है - आदेश की कुल राशि, आदेश आइटम गिनती आदि

+0

हां मैं अपनी वस्तुओं को टेबल से मेल खाने के लिए चाहता हूं, और मैं भूल रहा हूं कि डीडीडी के साथ मॉडल का डिज़ाइन हमेशा डेटाबेस के लिए 1 से 1 मैच नहीं है। आपके उदाहरण में ग्राहक वीओ को डीबी में "आदेश" तालिका में संग्रहित करने की आवश्यकता है? या ऑर्डर रिपॉजिटरी का कार्यान्वयन ग्राहक वीओ बनाने के लिए ग्राहक तालिका तक पहुंच सकता है? कहें कि क्या मैं आदेश के समय ग्राहक की जानकारी रखना नहीं चाहता हूं, लेकिन हमेशा नवीनतम ग्राहक जानकारी चाहते हैं? –

+0

सामान्य रूप से ग्राहक वीओ ऑर्डर तालिका में ऑर्डर तालिका में या एक अलग तालिका में संग्रहीत किया जाता है जिसमें ऑर्डर आईडी एफके होता है। यदि आप नवीनतम ग्राहक जानकारी चाहते हैं, तो शायद आपको यह देखने के लिए अपने मॉडल की समीक्षा करनी चाहिए कि आपको इसकी आवश्यकता क्यों है और एक लापता अवधारणा की तलाश है। यदि आपको ऑर्डर रिपॉजिटरी की तुलना में एक लापता अवधारणा नहीं मिलती है तो उसे ग्राहक तालिका से पढ़ा जा सकता है। या आपके पास एक ईवेंट हैंडलर हो सकता है जो जानकारी बदलते समय ऑर्डर में संग्रहीत ग्राहक जानकारी अपडेट करता है। –

+0

सुनिश्चित करें कि आदेश में नवीनतम ग्राहक जानकारी होनी चाहिए, या आदेश के समय वर्तमान जानकारी वास्तव में डिजाइन का सवाल है। लेकिन क्या मैं यह सोचने में सही हूं कि जहां तक ​​डीडीडी का सवाल है, वस्तुतः अलग-अलग योगों में निहित मूल्य प्रकारों के लिए ठीक है, उसी स्थिति में एक ही डेटाबेस तालिका में संग्रहीत किया जा सकता है? क्या यह ठीक होगा अगर ग्राहक। एड्रेस और ऑर्डर। शिपिंग एड्रेस, मॉडल में दोनों मान प्रकार, वास्तव में एक ही पते तालिका में संग्रहीत किए गए थे? कहें क्योंकि किसी अन्य संदर्भ में सभी ऑर्डर या ग्राहकों को एक विशिष्ट पते के लिए देखने की आवश्यकता हो सकती है? –

संबंधित मुद्दे