2012-05-04 58 views
15

An interesting thread तब आया जब मैंने अभी इस प्रश्न में टाइप किया था। मुझे नहीं लगता कि यह मेरे प्रश्न का उत्तर देता है हालांकि।क्या एक "समृद्ध डोमेन मॉडल" एकल उत्तरदायित्व सिद्धांत का उल्लंघन कर सकता है?

मैं नेट MVC3, जहां यह एक कमजोर मॉडल के लिए वांछनीय है के साथ एक बहुत काम कर रहा है। मॉडलों को देखें और मॉडल संपादित करें बेवकूफ डेटा कंटेनर के रूप में सबसे अच्छे हैं जिन्हें आप केवल नियंत्रक से देखने के लिए पास कर सकते हैं। किसी भी प्रकार का आवेदन प्रवाह नियंत्रकों से आना चाहिए, और विचार यूआई चिंताओं को संभालने के लिए हैं। एमवीसी में, हम मॉडल में कोई व्यवहार नहीं चाहते हैं।

लेकिन हम नहीं नियंत्रकों में किसी भी व्यापार तर्क या तो चाहते हैं। बड़े अनुप्रयोगों के लिए डोमेन कोड को मॉडल, विचारों और नियंत्रकों (और उस मामले के लिए सामान्य रूप से HTTP) से अलग और स्वतंत्र रखने के लिए सर्वोत्तम है। तो एक अलग परियोजना है जो किसी और चीज से पहले, एक डोमेन मॉडल (संस्थाओं और मूल्य वस्तुओं के साथ, डीडीडी के अनुसार समेकित में शामिल) प्रदान करती है।

मैं एक कमजोर मॉडल से डोमेन कोड में एक अमीर एक की ओर कदम दूर करने के लिए कुछ प्रयास कर चुके हैं, और मैं को देने की सोच रहा हूँ। ऐसा लगता है कि मुझे इकाई वर्ग होने की तरह लगता है जिसमें दोनों डेटा और व्यवहार एसआरपी का उल्लंघन करते हैं।

उदाहरण के लिए वेब पर एक बहुत ही आम परिदृश्य लें, ईमेल लिखते समय। कुछ घटनाओं को देखते हुए, ईमेल टेम्पलेट, ईमेल एड्रेस और कस्टम मान दिए गए ईमेल मैसेज ऑब्जेक्ट को लिखना डोमेन की ज़िम्मेदारी है। टेम्पलेट गुणों वाली इकाई के रूप में मौजूद है, और कस्टम मान उपयोगकर्ता द्वारा इनपुट के रूप में प्रदान किए जाते हैं। आइए तर्क के लिए भी कहें कि ईमेल मैसेज का पता बाहरी सेवा द्वारा प्रदान किया जा सकता है (IConfigurationManager.DefaultFromMailAddress)। उन आवश्यकताओं को देखते हुए यह एक अमीर डोमेन मॉडल की तरह लगता है EmailTemplate EmailMessage रचना की जिम्मेदारी दे सकता है:

public class EmailTemplate 
{ 
    public EmailMessage ComposeMessageTo(EmailAddress to, 
     IDictionary<string, string> customValues, IConfigurationManager config) 
    { 
     var emailMessage = new EmailMessage(); // internal constructor 
              // extension method 
     emailMessage.Body = this.BodyFormat.ApplyCustomValues(customValues); 
     emailMessage.From = this.From ?? config.DefaultFromMailAddress; 
     // bla bla bla 
     return emailMessage; 
    } 
} 

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

मैं एक समर्पित वर्ग जो एकमात्र जिम्मेदारी एक EmailMessage पिछले तर्क दिया रचना है में इस विधि पुनर्रचना समाप्त हो गया है, और मैं इसके साथ बहुत खुश हूं। असल में, मैं एनीमिक डोमेन पसंद करना शुरू कर रहा हूं क्योंकि इससे मुझे जिम्मेदारियों को अलग रखने में मदद मिलती है, जिससे कक्षाएं और यूनिट परीक्षण कम, अधिक संक्षिप्त और अधिक केंद्रित होते हैं। ऐसा लगता है कि संस्थाओं और अन्य डेटा वस्तुओं को "व्यवहार से रहित" बनाना जिम्मेदारी को अलग करने के लिए अच्छा हो सकता है। या मैं यहाँ ट्रैक बंद हूँ?

+1

एक समृद्ध डोमेन मॉडल केवल उस संदर्भ के लिए समृद्ध होने की आवश्यकता है जहां यह प्रासंगिक है। –

उत्तर

19

एक कमजोर मॉडल के बजाय एक अमीर डोमेन मॉडल के पक्ष में तर्क OOP का मूल्य प्रस्ताव है, जो एक दूसरे के बगल व्यवहार और डेटा रखने है में से एक पर टिका है। मुख्य लाभ कोड के बारे में तर्क में सहायता करता है जो encapsulation और एकजुटता है। एक समृद्ध डोमेन मॉडल को information expert पैटर्न के उदाहरण के रूप में भी देखा जा सकता है। इन सभी पैटर्न का मूल्य हालांकि काफी हद तक व्यक्तिपरक है। यदि डेटा और व्यवहार को अलग रखने के लिए यह अधिक सहायक है, तो हो सकता है, फिर भी आप अन्य लोगों पर विचार कर सकते हैं जो कोड को देख रहे होंगे। मैं जितना कर सकता हूं उतना ही encapsulate करना पसंद करते हैं। इस मामले में एक अमीर डोमेन मॉडल का अन्य लाभ कुछ संपत्तियों को निजी बनाने की संभावना होगी। यदि कोई संपत्ति केवल वर्ग पर एक विधि द्वारा उपयोग की जाती है, तो इसे सार्वजनिक क्यों करें?

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

+0

उत्कृष्ट जवाब, धन्यवाद। – danludwig

0

अच्छा, यह इस बात पर निर्भर करता है कि आप इसे कैसे देखना चाहते हैं।

एक और तरीका है: "एकल जिम्मेदारी सिद्धांत एक अमीर डोमेन मॉडल का उल्लंघन कर सकते हैं?"

दोनों दिशानिर्देश हैं। सॉफ़्टवेयर डिज़ाइन में कहीं भी "सिद्धांत" नहीं है। हालांकि, अच्छे डिजाइन और खराब डिजाइन हैं। एक अच्छी डिजाइन प्राप्त करने के लिए इन दोनों अवधारणाओं का उपयोग विभिन्न तरीकों से किया जा सकता है।