कनेक्टिविटी को कम करने और SOA के बारे में सोचने पर काम करते हुए, मैं इंटरफेस बनाकर टाइप करने के विचार के साथ आया।
शास्त्रीय डीडीडी में, आपको एक डोमेन को उजागर करने की आवश्यकता है - वस्तुओं और उनके संबंधों का संग्रह। लेकिन जब मैंने इस सिद्धांत को जीवन में लागू किया, तो मैं दो कठिनाइयों से मिला:
- यदि कोई बड़ा डोमेन और उसके आस-पास सेवाओं का एक समूह है, तो कक्षा सदस्यों तक पहुंच को नियंत्रित करना मुश्किल हो जाता है। यह इस तरह दिखता है: CreatedAt संपत्ति के साथ एक उपयोगकर्ता ऑब्जेक्ट है, जिसे मैं केवल सदस्यता सेवा को संपादित करने की अनुमति देना चाहता हूं। ठीक है, हम इंटरनैशनलविज़नटाइयो को मेम्बरशिप सर्विस का संकेत देते हुए लिखते हैं। अगला हमें एक ऑब्जेक्ट बनाने की आवश्यकता है, उदाहरण के लिए, कार, जिसमें पासडिस्टेंस संपत्ति है, जिसे मैं केवल कार सर्विस के लिए खोलना चाहता हूं। हम फिर से इंटरनैशनलविजीनटॉ के साथ जोड़तोड़ को दोहराते हैं, लेकिन यहां एक समस्या पैदा होती है: अब मेंबरशिप कार के माइलेज को बदल सकती है, और CarService - उपयोगकर्ता के पंजीकरण की तारीख।
- डीडीडी अभी भी एप्लिकेशन को "ईंट से ईंट" बनाने के लिए संभव नहीं बनाता है - बस आवश्यक मॉड्यूल को जोड़कर। वे कहते हैं कि यह रूबी में संभव है, इसलिए मैं .Net =) में समान आसानी चाहता हूं। लेकिन यह एक ही कारण से काम नहीं करता है - डोमेन को एक अलग असेंबली में आवंटित किया जाता है, और सेवा को कनेक्ट करते समय, आपको डोमेन से सभी आश्रित संस्थाओं को मैन्युअल रूप से खींचना होगा, क्योंकि उनके गुणों के माध्यम से, नई परियोजना में उनमें से अधिकांश की जरूरत नहीं होगी। यानी DDD सेवा कनेक्टिविटी की समस्या को हल करता है, लेकिन डोमेन कनेक्टिविटी अभी भी हल नहीं हुई है।
एक तरह से बाहर
- सेवा और इसकी संस्थाओं को एक मॉड्यूल में संयोजित करें। यह दो विधानसभाओं (डोमेन और सेवा) या एक एकल विधानसभा होगी - इससे कोई फर्क नहीं पड़ता। लक्ष्य मॉड्यूल की सभी कार्यक्षमता को बस उस विधानसभा के संदर्भ में जोड़कर कनेक्ट करना है जिसमें एप्लिकेशन की संरचना निष्पादित होती है (उदाहरण के लिए AppCore)।
ऐसा करने के बाद, आपको किसी तरह विभिन्न मॉड्यूल के डोमेन के बीच संचार की संभावना को छोड़ने की आवश्यकता है। यह संभावना है कि हमारे उदाहरण में यह आवश्यक होगा कि टाइप यूजर की Car.Owner संपत्ति को लागू किया जाए, और फिर House.Owner, CableTv.User, आदि। सदस्यता के संदर्भ को जोड़ना एक विकल्प नहीं है, यह पहले से ही मुख्य विचार का खंडन करता है - मॉड्यूल को कनेक्ट होने से रोकने के लिए।
एक समाधान के लिए विचार
विधानसभा में ऐसे सभी निर्भरता का चयन करें, लेकिन पूरी संस्थाओं के साथ नहीं, बल्कि डमी इंटरफेस के साथ। इस उदाहरण में, यह खाली IUser इंटरफ़ेस होगा। फिर, प्रत्येक मॉड्यूल (इसके बूटस्ट्रैपर में) के प्रारंभ के दौरान, इस इंटरफ़ेस को उस मॉड्यूल (ICarOwner) के अंदर दर्शाया गया है, जिसके साथ आप इस मॉड्यूल के भीतर उपयोगकर्ता के लिए आवश्यक कुछ गुण निर्दिष्ट कर सकते हैं।
इस प्रकार, प्रत्येक मॉड्यूल अपने स्वयं के क्षेत्रों के साथ IUser इंटरफ़ेस का पूरक है। फिर आपको एक कारखाने को लागू करने की आवश्यकता है, जो इंटरफेस की सूची के आधार पर, एक एकल उपयोगकर्ता प्रकार बनाएगा जिसे ऐपस्टोर में कैश किया जाएगा।
पेशेवरों और विपक्ष:
+ प्रत्येक मॉड्यूल केवल उन क्षेत्रों के बारे में जानता है जिनकी उसे आवश्यकता है
+ बुनियादी इंटरफेस के अपवाद के साथ, मॉड्यूल पूरी तरह से स्वतंत्र होंगे।
+ एक नया मॉड्यूल जोड़ते समय, दृढ़ता के लिए आवश्यक गुणों को स्वचालित रूप से जोड़ा जाएगा। यानी मॉड्यूल जोड़ते समय, Sql- योजना स्वचालित रूप से आवश्यक तालिकाओं, स्तंभों और अन्य वस्तुओं के साथ फिर से भर जाएगी।
- विचार अभी तक लागू नहीं हुआ है =)। लेकिन जो कोई इस दृष्टिकोण को लागू करना चाहता है, उसके लिए यह एक प्लस होगा - वह इसे जीवन में लाने वाला पहला व्यक्ति होगा।
लक्ष्य प्लग एंड प्ले कार्यक्षमता बनाना है।
हमें आदेश की आवश्यकता है - OrdersLib के लिए एक संदर्भ जोड़ा गया, लॉन्च किया गया, यह है!
डेटाबेस स्वचालित रूप से नए टेबल, कॉलम, लिंक के साथ अपडेट किया जाता है, जो कि OrdersLib के काम के लिए आवश्यक हैं। उपयोगकर्ता के पास स्वचालित रूप से User.Orders होंगे, आदि।
कोड को अनुकूलित करने के लिए कोई काम नहीं, केवल जहां आवश्यक हो एक्सटेंशन।
कैसे समझें कि उपयोगकर्ता वस्तु क्या है? दो विकल्प हैं:
- एक सामान्य इंटरफ़ेस की कोड पीढ़ी, जो एक कारखाने के निर्माण को भी सरल बनाएगी
- विकसित अनुप्रयोग के वातावरण में विकास। Intellisense बाईटेकोड नहीं पढ़ेगा, लेकिन गतिशील वस्तु का वास्तविक उदाहरण।
पहला तरीका सख्त टाइपिंग को संरक्षित करेगा, दूसरा विकास को पूरी तरह से गतिशील बना देगा।