2008-10-01 15 views
15

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

हालांकि मुझे कॉल श्रृंखला के नीचे वस्तुओं का ज्ञान रखने के लिए मेरी कॉल श्रृंखला को ऊपर उठाने की आवश्यकता है।

क्या यह डेमेटर का कानून तोड़ता है? यदि ऐसा है तो क्या इससे कोई फर्क पड़ता है?

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

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

+1

क्या आप कुछ उदाहरण कोड पोस्ट कर सकते हैं? यदि आप foo.bar()। Baz() कर रहे हैं तो हाँ, आप डेमेटर के कानून को तोड़ रहे हैं। क्या आप कह रहे हैं कि आप ऐसा कर रहे हैं? – asterite

उत्तर

11

निर्भरता इंजेक्शन डेमेटर के कानून को तोड़ सकता है। यदि आप उपभोक्ताओं को निर्भरताओं के इंजेक्शन करने के लिए मजबूर करते हैं। यह स्थैतिक कारखाने के तरीकों, और डी ढांचे के माध्यम से बचा जा सकता है।

आप दोनों अपनी वस्तुओं को इस तरह से डिजाइन कर सकते हैं कि उन्हें निर्भरता की आवश्यकता होती है, और साथ ही इंजेक्शन (फैक्ट्री फ़ंक्शंस और डी फ्रेमवर्क) को स्पष्ट किए बिना उनका उपयोग करने के लिए एक तंत्र हो।

+0

मुझे लगता है कि आपने इसे खींचा है। इस प्रश्न के कुछ अन्य उत्तर प्रश्नकर्ता की विशिष्ट स्थिति पर ध्यान केंद्रित नहीं कर रहे हैं। – moffdub

+0

क्या आप कृपया 'उपभोक्ता' शब्द पर विस्तार कर सकते हैं? – meowsqueak

+0

इस मामले में कक्षा का उपभोक्ता कोई अन्य कोड है जो उस वर्ग पर विधियों को कॉल करता है। –

1

क्या यह कानून तोड़ता है?
कड़ाई से बोलते हुए, मुझे लगता है कि यह करता है।
क्या इससे कोई फर्क पड़ता है?
कानून तोड़ने का मुख्य खतरा यह है कि आप अपना कोड अधिक भंगुर बनाते हैं।
यदि आप वास्तव में इसे केवल परीक्षणों में रखते हैं, तो ऐसा लगता है कि खतरे बहुत खराब नहीं है।
मिटिगेशन
Law of Demeter की मेरी समझ यह है कि इसके बाद "रैपर विधियां" हो सकती हैं जो सीधे वस्तुओं में कॉल करने से रोकती हैं।

3

यह कैसे टूटता है? DI पूरी तरह से कम से कम ज्ञान के विचार में फिट बैठता है। डि आप कम युग्मन देता है - वस्तुओं एक दूसरे पर कम प्रतिवादी हैं।

विकिपीडिया हवाला देते हुए:

... एक वस्तु एक एक सेवा अनुरोध कर सकते हैं (फोन एक विधि) एक वस्तु उदाहरण बी की, लेकिन वस्तु एक नहीं अभी तक उपयोग करने के लिए बी वस्तु "के माध्यम से पहुंच" कर सकते हैं एक और वस्तु ...

आमतौर पर DI उसी तरह काम करता है, यानी आप इंजेक्शन घटकों द्वारा प्रदान की जाने वाली सेवाओं का उपयोग करते हैं। बी की निर्भरता में से कुछ यह बी के बारे में ज्यादा जानता है अर्थात् क्या आपके वस्तु तक पहुँचने का प्रयास है - कि उच्च युग्मन की ओर जाता है और डि

के विचार

टूट जाता है फिर भी मैं का ज्ञान होना वस्तुओं की आवश्यकता होती है कर रहा हूँ उच्च मेरे कॉल श्रृंखला कॉल श्रृंखला

कुछ उदाहरण नीचे वस्तुओं?

2

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

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

1

डेमेटर का कानून निर्दिष्ट करता है कि ऑब्जेक्ट ओ की विधि एम एम के अंदर बनाई गई/तत्काल वस्तुओं पर विधियों को कॉल कर सकती है। हालांकि, कुछ भी नहीं है जो यह निर्दिष्ट करता है कि ये ऑब्जेक्ट्स कैसे बनाए गए थे। मुझे लगता है कि इन्हें बनाने के लिए मध्यस्थ वस्तु का उपयोग करना बिल्कुल ठीक है, जब तक कि उस वस्तु का उद्देश्य केवल जीवन में ही है - आपकी ओर से अन्य वस्तुओं को बनाना। इस अर्थ में, DI डेमेटर के कानून को तोड़ता नहीं है।

0

निर्भर करता है :-)

मुझे लगता है कि शीर्ष जवाब भी एक रूपरेखा कोड का एक बहुत निर्भरता इंजेक्शन का उपयोग करता है और उच्च स्तर की वस्तुओं का इंजेक्शन के साथ, सही नहीं है। फिर आप कई निर्भरताओं के साथ स्पेगेटी कोड प्राप्त करते हैं।

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

0

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

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

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

हां, डेमेटर का कानून एसओपी सेवाओं पर लागू किया जा सकता है। लेकिन फिर, कानून मूल रूप से ओओपी में रिच मॉडल के लिए डिज़ाइन किया गया था। और यद्यपि कानून सेवाओं पर लागू हो सकता है, उचित निर्भरता इंजेक्शन स्वचालित रूप से डेमेटर के कानून को पूरा करता है। उस अर्थ में, DI संभवतः कानून को तोड़ नहीं सका।

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

निम्न उदाहरण जो वास्तविक अलग समाधान, उनके संदर्भ, और लागू करने कोड से पता चलता समीक्षा करें: "। कोर"

In SOA, DI doesn't allow breaking of LoD

ऊपरी-दाएं, हमने NuGet और NPM पर बहुत से पैकेजों में "कोर" प्रोजेक्ट है जिसमें मॉडल, इंटरफेस और संभवतः यहां तक ​​कि डिफ़ॉल्ट कार्यान्वयन भी हैं। कोर कभी भी बाहरी पर कभी भी निर्भर नहीं होना चाहिए।

शीर्ष-बाईं ओर, हमारे पास कोर का बाहरी कार्यान्वयन है। कार्यान्वयन कोर पर निर्भर करता है, और इसलिए इसका ज्ञान है।

नीचे बाईं ओर, हमारे पास एक स्टैंडअलोन डोमेन है। डोमेन के कोर के कुछ कार्यान्वयन पर निर्भरता है, लेकिन को कार्यान्वयन के बारे में जानने की आवश्यकता नहीं है।

यह वह जगह है जहां मैं इंगित करता हूं कि न तो डोमेन और न ही कार्यान्वयन एक-दूसरे को पता है। एक 0% मौका है कि या तो कभी भी दूसरे (या उससे परे) तक पहुंच सकता है, क्योंकि वे यह भी नहीं जानते कि वे मौजूद हैं। डोमेन केवल जानता है कि एक अनुबंध है, और यह किसी भी तरह से इंजेक्शन द्वारा किए गए तरीकों का उपभोग कर सकता है।

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

वास्तव में एक ही प्रोजेक्ट में सब कुछ तोड़ने का एक तरीका है, कंक्रीट तत्काल सेवाओं के, निजी क्षेत्रों के बजाय अपनी निर्भरताओं को सार्वजनिक गुण बनाएं, फिर भी निर्भरता-इंजेक्शन (भयानक) करें, और उसके बाद सेवाएं निर्भरताओं की निर्भरताओं में कॉल करें। लेकिन यह बुरा होगा, मैके। आपको कोशिश करनी होगी ऐसा करने के लिए बुरा हो।

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

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

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