2009-01-22 24 views
8

मैं वर्तमान में डेटा मैपर्स का उपयोग करने के लिए एक एप्लिकेशन को फिर से लिखने पर काम कर रहा हूं जो डोमेन परत से डेटाबेस को पूरी तरह से सारणीबद्ध करता है। हालांकि, मैं अब सोच रहा हूँ जो डोमेन वस्तुओं के बीच संबंधों से निपटने के लिए बेहतर तरीका है: सीधे डोमेन वस्तु क्या डोमेन ऑब्जेक्ट्स को डेटा एक्सेस लेयर से अवगत कराया जाना गलत है?

  • में लिखें संबंध तर्क के भीतर संबंधित डेटा नक्शाकार से

    1. कॉल आवश्यक खोज() विधि देशी डेटा मैपर (जो उदाहरण पीओईएए में करते हैं) और फिर डोमेन ऑब्जेक्ट के भीतर देशी डेटा मैपर फ़ंक्शन को कॉल करते हैं।

    या तो यह क्रम बनाए रखने के 'फैट मॉडल, स्किनी नियंत्रक' मंत्र में मुझे उस रहा है, डोमेन वस्तुओं (डेटा मानचित्रकारों के बारे में पता है कि क्या यह अपने स्वयं के होने रहना होगा या वे के लिए उपयोग किया है कि सिस्टम में अन्य मैपर)। इसके अतिरिक्त ऐसा लगता है कि विकल्प 2 अनावश्यक रूप से डेटा एक्सेस लेयर को जटिल करता है क्योंकि यह एक डेटा मैपर को सीमित करने के बजाय एकाधिक डेटा मैपर में टेबल एक्सेस लॉजिक बनाता है।

    तो, डोमेन ऑब्जेक्ट्स को संबंधित डेटा मैपर्स से अवगत कराने और डोमेन ऑब्जेक्ट्स से सीधे डेटा ऑब्जेक्ट फ़ंक्शंस को कॉल करना गलत है?

    अद्यतन: ये केवल दो समाधान हैं जिन्हें मैं डोमेन ऑब्जेक्ट्स के बीच संबंधों के मुद्दे को संभालने के लिए कल्पना कर सकता हूं। एक बेहतर विधि दिखाने वाला कोई भी उदाहरण स्वागत होगा।

  • उत्तर

    7

    मुझे डर है कि आपने रिपोजिटरी पैटर्न के इरादे को थोड़ा गलत समझा है।

    interface EmployeeRepository 
    { 
        List<Employee> retrieveBy(Criteria someCriteria); 
        void store(Employee someEmployee); 
        int countOf(Criteria someCriteria); 
        // convenience methods 
        Employee retrieveById(String id); 
        Employee retrieveBySSN(String ssn); 
    } 
    

    इस कोड के ग्राहकों पता नहीं है कि क्या संग्रह आप की तरह, स्मृति में है:

    भंडार किसी विशेष डोमेन वस्तु का इन-स्मृति संग्रह, आम तौर पर की तरह व्यवहार करने के लिए एक समग्र जड़ होती है कुछ मामलों में यूनिट-परीक्षण, या किसी ओआरएम मैपर से बात करना, या दूसरों में संग्रहीत प्रक्रिया को कॉल करना, या कुछ डोमेन ऑब्जेक्ट्स के लिए कैश बनाए रखना है।

    यह अभी भी आपके प्रश्न का उत्तर नहीं देता है। असल में, आप संभावित रूप से डोमेन ऑब्जेक्ट्स को() और लोड() विधियों को सही भंडार में भेज सकते हैं। मुझे नहीं लगता कि यह जाने का सही तरीका है क्योंकि दृढ़ता व्यापार डोमेन का लगभग कभी हिस्सा नहीं है, और यह आपके डोमेन ऑब्जेक्ट को बदलने के एक से अधिक कारण देता है।

    अधिक रैंपिंग के लिए this related question देखें।

    इस जवाब पर कुछ टिप्पणियों के जवाब में:

    एक वैध आलोचना। हालांकि, मैं अभी भी उलझन में हूं कि डोमेन ऑब्जेक्ट या संबंधित डोमेन ऑब्जेक्ट्स का संग्रह किसी मौजूदा डोमेन ऑब्जेक्ट के संदर्भ के दौरान कैसे उलझन में है। - गैब्रियल 1836

    मान लें कि एक कर्मचारी के पास कई कौशल हैं। मैं कर्मचारी भंडार इस तरह एक कौशल भंडार बुला के साथ कुछ भी गलत नहीं देखें:

    // assume EmployeeRepository talks to a DB via sprocs 
    public Employee retrieveById(String id) 
    { 
        ResultSet employeeResultSet = this.database.callSproc("PROC_GetEmployeeById", 
         new Object[] { id }); 
    
        List<Skill> skills = 
         new SkillRepository().retrieveBy(new EqualsCriteria("EmployeeId", id)); 
    
        Employee reconstructed = new EmployeeFactory().createNew(). 
                fromResultSet(employeeResultSet). 
                withSkills(skills). 
                build(); 
    
        return reconstructed;  
    } 
    

    एक और मार्ग है के बजाय कौशल भंडार बुला, कर्मचारी भंडार फोन, इस उदाहरण में है, संग्रहीत प्रक्रिया परिणाम सेट लोड करने के लिए कौशल के लिए, कौशल की सूची प्राप्त करने के लिए एक कौशल फैक्टरी को प्रतिनिधि दें।

    मैं भंडार के लिए एक कॉल नहीं कर सकते और यह डेटा नक्शाकार के लिए एक कॉल जारी करता है या इन-स्मृति वस्तु अपनी चिंता का विषय है लोड करता है, है ना? - गैब्रियल 1836

    बिल्कुल सही। मैं आम तौर पर इस तरह अपने यूनिट परीक्षणों में पूरे डेटा स्तर को नकल करता हूं।

    +0

    एक वैध आलोचना। हालांकि, मैं अभी भी उलझन में हूं कि एक मौजूदा डोमेन ऑब्जेक्ट के संदर्भ में एक डोमेन ऑब्जेक्ट या संबंधित डोमेन ऑब्जेक्ट्स का संग्रह कैसे प्राप्त करें। –

    +0

    क्या मैं रिपोजिटरी को कॉल नहीं कर सकता हूं और क्या यह डेटा मैपर को कॉल जारी करता है या ऑब्जेक्ट लोड करता है ऑब्जेक्ट इसकी चिंता है, है ना? –

    7

    हां। खुद से पूछें कि डोमेन वस्तु ऐसी चीज़ के बारे में क्यों जानती है? क्यों नहीं, लेकिन कैसे? आप अपने डीएएल को अपने डोमेन ऑब्जेक्ट में इंजेक्ट करने जा रहे हैं?

    डोमेन को एसआरपी का पालन करना चाहिए बस बाकी सब कुछ जीना चाहिए। जब आप अपने डोमेन को पार करते हैं तो आपको अनजान होना चाहिए यदि उन गुणों को आलसी लोडिंग के माध्यम से पॉप्युलेट किया गया था, या तत्काल से हाइड्रेटेड किया गया था।

    मैंने एक डोमेन मॉडल लिखा है जिसमें डीएएल ऑब्जेक्ट्स था और यह बनाए रखने के लिए एक दुःस्वप्न था। तब मैंने एनएचबीर्नेट को सीखा और मेरे डोमेन में पीओसीओ और उनके संबंधित व्यावसायिक तर्क शामिल हैं जिन्हें मैं समाहित करना चाहता हूं।

    [संपादित करें]

    यहाँ और अधिक जानकारी है। अगर मैं इसे समझाने की कोशिश करता तो मैं केवल खुद को शर्मिंदा कर दूंगा। मैं केवल उपयोगकर्ता के रूप में कार्यान्वयन के बारे में बात कर सकता हूं। Domain Model management पर एक अच्छा लेख यहां दिया गया है। आप क्या रुचि रखते हैं इंटरसेप्टर, और mixins के कार्यान्वयन है।

    public class Employee 
    { 
        public Employee() 
        { 
         Skills = new List<Skill>(); 
        } 
    
        public string Name { get; set; } 
        public IList<Skill> Skills { get; private set; } 
    
        public void AddSkill(Skill skill) 
        { 
         // Perform Domain specific validation here... 
    
         Skills.Add(skill); 
        } 
    } 
    

    आप देख सकते हैं, मेरे डेटा का उपयोग की जरूरत है जो भी मेरी डोमेन डिजाइन पर लागू नहीं:

    उन उपकरणों के साथ आप इस प्रकार एक कर्मचारी वर्ग लिख सकते हैं।

    +0

    क्या आप उदाहरण के लिए एक उदाहरण प्रदान कर सकते हैं कि आप मौजूदा डोमेन ऑब्जेक्ट को मौजूदा में कैसे लोड करते हैं? उदाहरण के लिए आप एक कर्मचारी के लिए कौशल का संग्रह कैसे लोड करते हैं? –

    +0

    आप रिपोजिटरी ऑब्जेक्ट को ऐसा करना चाहते हैं ...डोमेन मॉडल निरंतर अज्ञान होना चाहिए, हालांकि एक और वस्तु होनी चाहिए जो दृढ़ता के बारे में जानती है जो इसे संभालती है। – Webjedi

    +0

    अद्यतन के लिए धन्यवाद। यह विदेशी कुंजी मैपिंग पर फाउलर के नमूना कोड से बेहद परिचित दिखता है। :-) –

    0

    कुछ और पढ़ने और उचित पैटर्न खोजने के बाद, मैंने the Repository Pattern पर ठोकर खाई।

    जो मैं देख सकता हूं उससे यह एक अनुमानित समाधान है जो डोमेन ऑब्जेक्ट्स को डोमेन ऑब्जेक्ट्स को उचित रूप से सारणीबद्ध करने के लिए उपयुक्त डेटा मैपर को प्रश्नों को सही तरीके से प्रतिनिधि करने की अनुमति देता है, जबकि डोमेन ऑब्जेक्ट और डेटा मैपर को पूरी तरह से सारणीबद्ध छोड़ दिया जाता है।

    0

    मुझे असहमत है, मुझे लगता है कि डोमेन ऑब्जेक्ट सार फैक्ट्री के माध्यम से रेपॉजिटरीज़ तक पहुंच सकता है।

    public class Client 
    { 
        public void ChangeZipCode(string zipCode) 
        { 
        // This method access memory or database depending on the factory context 
        bool zipCodeExists = RepositoryFactory.Get<IZipCode>().Exists(zipCode); 
        this.zipCode = zipCode; 
        } 
    } 
    

    इस पद्धति का उपयोग करके, यह सब आपके कोड लेकिन केवल भंडार कारखाने से अधिक भंडार इंटरफेस इंजेक्षन करने के लिए आवश्यक नहीं है।

    public abstract class RepositoryFactory 
    { 
        // Class operations 
        private static _globalInstance; 
        public static CreateGlobalInstance(RepositoryFactory factory) 
        { 
        _glocalInstance = factory; 
        } 
        public static I Get<I>() 
        { 
        return _globalInstance.Get<I>(); 
        } 
        ///////////////////// 
    
        ///// this operation should be inherited by: 
        ///// * NHibernateRepositoryFactory // 
        ///// * Linq2SqlRepositoryFactory //// 
        ///// * NUnitRepositoryFactory ///////  
        ///// it depends in your context //////////////////////// 
        public abstract I GetRepository<I>(); 
    } 
    

    मैं अपने यूनिट परीक्षणों में किसी भी समस्या के बिना वर्षों से ऐसा कर रहा हूं।

    इसलिए निर्भरता इंजेक्शन केवल इस वर्ग रिपोजिटरी फैक्टरी में आवश्यक है।