क्या मुझे डोमेन ऑब्जेक्ट में रिपॉजिटरी का उपयोग करना चाहिए या डोमेन लेयर को सर्विस लेयर पर वापस धकेलना चाहिए?


10

मैं एक लेनदेन स्क्रिप्ट की दुनिया से आया हूं और मैं अभी DDD पर एक नज़र रखना शुरू कर रहा हूं। मैं डेटाबेस दृढ़ता के साथ DDD डिज़ाइन को एकीकृत करने के सही तरीके से अनिश्चित हूं। यह वही है जो मेरे पास है:

OrganisationService नामक एक सेवा वर्ग जिसके इंटरफ़ेस में संगठन डोमेन ऑब्जेक्ट्स के इंस्टेंस को पुनर्प्राप्त करने और सहेजने के तरीके हैं। संगठन एक समग्र जड़ है और इससे संबंधित अन्य आंकड़े हैं: सदस्य और लाइसेंस। EF6 डेटाबेस पहले DBContext का उपयोग OrganisationService के भीतर OrganisationDB संस्थाओं और संबंधित सदस्यDB और लाइसेंसडीबी संस्थाओं को पुनः प्राप्त करने के लिए किया जाता है। ऑर्गनाइजेशन सर्विस द्वारा पुनर्प्राप्त और संगठन डोमेन ऑब्जेक्ट में लोड होने पर ये सभी अपने डोमेन ऑब्जेक्ट क्लास समकक्षों में बदल जाते हैं। यह ऑब्जेक्ट ऐसा दिखता है:

public class Organisation
{
    public IList<Member> Members { get; set; }
    public IList<License> Licenses { get; set; }
}

मैं ऑर्गनाइजेशन सर्विस में रिपोजिटरी पैटर्न का उपयोग नहीं कर रहा हूं ... मैं ईईएफ का उपयोग रिपॉजिटरी के रूप में ही कर रहा हूं क्योंकि ऐसा लगता है कि ईएफ 6 ने रिपॉजिटरी को अब बेमानी बना दिया है।

डिजाइन में इस बिंदु पर संगठन डोमेन ऑब्जेक्ट एनीमिक है: यह ईएफ पोको संगठन वर्ग जैसा दिखता है। OrganisationService वर्ग एक रिपॉजिटरी की तरह दिखता है!

अब मुझे तर्क जोड़ना शुरू करना होगा। इस तर्क में एक संगठन लाइसेंस और सदस्यों का प्रबंधन शामिल है। अब लेन-देन की स्क्रिप्ट के दिनों में मैं इन परिचालनों को संभालने के लिए ऑर्गनाइजेशन सर्विस में तरीके जोड़ूंगा और डीबी के साथ बातचीत करने के लिए रिपॉजिटरी में कॉल करूंगा, लेकिन डीडीडी के साथ मेरा मानना ​​है कि इस तर्क को संगठन डोमेन ऑब्जेक्ट के भीतर ही समझाया जाना चाहिए ...

यह वह जगह है जहां मैं इस बात से अनिश्चित हूं कि मुझे क्या करना चाहिए: मुझे इस डेटा को तर्क के हिस्से के रूप में डेटाबेस में वापस रखना होगा। क्या इसका मतलब यह है कि मुझे ऐसा करने के लिए संगठन डोमेन ऑब्जेक्ट के भीतर DbContext का उपयोग करना चाहिए? क्या डोमेन ऑब्जेक्ट खराब अभ्यास के भीतर रिपॉजिटरी / ईएफ का उपयोग कर रहा है? यदि हां, तो यह दृढ़ता कहां से है?

public class Organisation
{
    public IList<Member> Members { get; set; }
    public IList<License> Licenses { get; set; }

    public void AddLicensesToOrganisation(IList<License> licensesToAdd)
    {
        // Do validation/other stuff/

        // And now Save to the DB???
        using(var context = new EFContext())
        {
            context.Licenses.Add(...
        }

        // Add to the Licenses collection in Memory
        Licenses.AddRange(licensesToAdd);
    }
}

क्या मुझे इसके बजाय सिर्फ संगठन डोमेन ऑब्जेक्ट को मेमोरी में म्यूट करना चाहिए और फिर इसे ऑर्गनाइजेशन सर्विस को दृढ़ता के लिए वापस धकेलना चाहिए? तब मुझे ट्रैक करना होगा कि वास्तव में ऑब्जेक्ट पर क्या बदला गया है (जो कि ईएफ अपने स्वयं के पीओसीओ के लिए करता है! मुझे यह महसूस करने में आ रहा है कि ईएफ केवल रिपॉजिटरी प्रतिस्थापन नहीं है, बल्कि डोमेन परत भी हो सकता है!)

यहाँ किसी भी मार्गदर्शन की सराहना की है।

जवाबों:


2

आप या तो दृष्टिकोण ले सकते हैं और यह अच्छी तरह से काम कर सकता है - बेशक, पेशेवरों और विपक्ष हैं।

एंटिटी फ्रेमवर्क निश्चित रूप से आपके डोमेन संस्थाओं का उपयोग करने के लिए है। यह तब अच्छी तरह से काम करता है जब आपकी डोमेन इकाइयाँ और डेटा इकाइयाँ एक ही वर्ग हों। यह बहुत अच्छा है अगर आप अपने लिए परिवर्तनों पर नज़र रखने के लिए ईएफ पर भरोसा कर सकते हैं, और context.SaveChanges()जब आप अपने लेन-देन के काम के साथ समाप्त हो जाते हैं तो बस कॉल करें । इसका अर्थ यह भी है कि आपकी सत्यापन विशेषताओं को दो बार, एक बार आपके डोमेन मॉडल पर और एक बार आपकी स्थायी संस्थाओं पर सेट करने की आवश्यकता नहीं है - आपके व्यवसाय तर्क में ऐसी चीज़ों की जाँच [Required]या [StringLength(x)]जाँच की जा सकती है , जिससे आप प्रयास करने से पहले अमान्य डेटा स्थिति को पकड़ सकते हैं। DB लेनदेन करें और प्राप्त करेंEntityValidationException। अंत में, कोड के लिए त्वरित है - आपको मैपिंग परत या रिपॉजिटरी लिखने की आवश्यकता नहीं है, लेकिन इसके बजाय सीधे ईएफ संदर्भ के साथ काम कर सकते हैं। यह पहले से ही एक भंडार और काम की इकाई है, इसलिए अमूर्त की अतिरिक्त परतें कुछ भी पूरा नहीं करती हैं।

अपने डोमेन और निरंतर संस्थाओं के संयोजन के लिए एक नकारात्मक पक्ष यह है कि आप [NotMapped]अपने गुणों में बिखरे हुए गुणों का एक गुच्छा के साथ समाप्त होते हैं। अक्सर, आप डोमेन-विशिष्ट गुण चाहते हैं जो या तो केवल स्थायी डेटा पर फ़िल्टर होते हैं, या बाद में आपके व्यावसायिक तर्क में सेट होते हैं और आपके डेटाबेस में वापस नहीं बने रहते हैं। कुछ बार, आप अपने डेटा को अपने डोमेन मॉडल में एक ऐसे तरीके से व्यक्त करना चाहते हैं जो डेटाबेस के साथ बहुत अच्छा काम नहीं करता है - उदाहरण के लिए, जब एनम का उपयोग करते हैं, तो Entity इन्हें एक intकॉलम में मैप करेगी - लेकिन शायद आप मैप करना चाहते हैं उन्हें एक मानव-पठनीय के लिए string, इसलिए आपको डेटाबेस की जांच करते समय लुकअप से परामर्श करने की आवश्यकता नहीं है। फिर आप एक stringसंपत्ति के साथ समाप्त होते हैं जो मैप की जाती है, एenumवह संपत्ति जो (लेकिन स्ट्रिंग और मैप्स को एनम को मिलती है) नहीं है, और एक एपीआई जो दोनों को उजागर करता है! इसी प्रकार, यदि आप संदर्भों में जटिल प्रकारों (तालिकाओं) को जोड़ना चाहते हैं, तो आप एक mappedअन्यटेबल और एक अनमैप्ड प्रॉपर्टी के साथ वाइंड अप कर सकते ComplexTypeहैं, दोनों ही आपकी कक्षा में सार्वजनिक रूप से सामने आते हैं। यह किसी ऐसे व्यक्ति के लिए भ्रामक हो सकता है जो परियोजना से परिचित नहीं है, और अनावश्यक रूप से आपके डोमेन मॉडल को दोष देता है।

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

मैन्युअल रूप से आपकी इकाई परिवर्तनों पर नज़र रखने की परेशानी से बचने के लिए एक चाल है कि आप अपने डोमेन मॉडल में संबंधित अनुषंगी इकाई आईडी को संग्रहीत करें। यह आपकी मैपिंग परत द्वारा स्वचालित रूप से भरा जा सकता है। फिर, जब आपको ईएफ पर वापस परिवर्तन जारी रखने की आवश्यकता होती है, तो किसी भी मैपिंग करने से पहले संबंधित स्थायी इकाई को पुनः प्राप्त करें । फिर जब आप परिवर्तनों को मैप करते हैं, तो ईएफ उन्हें स्वचालित रूप से पता लगाएगा, और आप context.SaveChanges()उन्हें हाथ से ट्रैक किए बिना कॉल कर सकते हैं ।

public class OrganisationService
{
    public void PersistLicenses(IList<DomainLicenses> licenses) 
    {
        using (var context = new EFContext()) 
        {
            foreach (DomainLicense license in licenses) 
            {
                var persistedLicense = context.Licenses.Find(pl => pl.Id == license.PersistedId);
                MappingService.Map(persistedLicense, license); //Right-left mapping
                context.Update(persistedLicense);
            }
            context.SaveChanges();
        }
    }
}

क्या डेटा की विभिन्न जटिलता के साथ अलग-अलग दृष्टिकोणों को जोड़ते समय कोई समस्या है? यदि आपके पास डीबी के लिए अच्छी तरह से नक्शे में कुछ है, तो सीधे ईएफ का उपयोग करें। यदि आपके पास ऐसा कुछ है, जो ईएफ का उपयोग करने से पहले मैपिंग / अमूर्तता का परिचय देता है।
व्यंग्यात्मक

@Euphoric डोमेन और DB के अंतर को मानचित्रण में संभाला जा सकता है। मैं एक ऐसे उपयोग के मामले के बारे में नहीं सोच सकता जहाँ डोमेन को दो बार जोड़ना (लगातार और लगातार) और हाथ से ट्रैकिंग बदलना विशेष मामलों के लिए मैपिंग जोड़ने की तुलना में कम काम है। क्या आप मुझे एक इशारा कर सकते हैं? (मुझे लगता है कि NHibernate का उपयोग करना, शायद EF अधिक सीमित है?)
Firo

बहुत उपयोगी, व्यावहारिक और जानकारीपूर्ण उत्तर। जवाब के रूप में चिह्नित करना। धन्यवाद!
मृलेन

3

मैं नहीं जानता कि ईएफ 6 लेकिन अन्य ओआरएम इसे पारदर्शी रूप से संभालते हैं, इसलिए आपको लाइसेंस को संदर्भ में स्पष्ट रूप से जोड़ना होगा, परिवर्तन को सहेजते समय यह पता लगाएगा। तो विधि नीचे हो जाएगी

public void AddLicenses(IEnumerable<License> licensesToAdd)
{
    // Do validation/other stuff/
    // Add to the Licenses collection in Memory
    Licenses.AddRange(licensesToAdd);
}

और इसके चारों ओर कोड

var someOrg = Load(orgId);

someOrg.AddLicenses(someLicences);

SaveChanges();

मेरी डोमेन ऑब्जेक्ट एंटिटीज़ नहीं हैं, इसलिए उन्हें लाइसेंस संग्रह में जोड़ना, जो कि सिर्फ एक सूची है, इसे काट नहीं पाएंगे। प्रश्न ईएफ के बारे में इतना अधिक नहीं है, हालांकि यह वह जगह है जहां वास्तविक दृढ़ता होती है। ईएफ में सभी दृढ़ता एक संदर्भ दायरे में होनी चाहिए। सवाल यह है कि यह कहाँ से है?
मृलेन

2
डोमेन इकाइयाँ और निरंतर इकाइयाँ समान हो सकती हैं अन्यथा आपको अमूर्तता की एक और परत का परिचय देना चाहिए जो कि 99% समय का कोई मूल्य नहीं जोड़ता है और ट्रैकिंग खो जाती है।
फिरो
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.