निर्भरता उलटा सिद्धांत का उपयोग करके कार्यान्वित किया जाता है। निर्भरता उलटा

घर / झगड़ा

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

एक)। ऊपरी स्तर के मॉड्यूल निचले स्तर के मॉड्यूल पर निर्भर नहीं होने चाहिए। दोनों स्तरों पर मॉड्यूल को अमूर्तता पर निर्भर होना चाहिए।

2))। सार विवरण पर निर्भर नहीं होना चाहिए। विवरण अमूर्त पर निर्भर होना चाहिए।

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

पब्लिक क्लास बार्ड (निजी गिटार गिटार; पब्लिक बार्ड (गिटार गिटार) (यह गिटार = गिटार;) पब्लिक वॉयड प्ले () (गिटार.प्ले ();))

पब्लिक क्लास बार्ड (

निजी गिटार गिटार;

सार्वजनिक बार्ड (गिटार गिटार)

यह। गिटार = गिटार;

सार्वजनिक शून्य खेल ()

गिटार। प्ले Play();

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

फ़ाइल Instrument.java:

सार्वजनिक इंटरफ़ेस साधन (शून्य खेल (); )

सार्वजनिक इंटरफ़ेस साधन (

शून्यप्ले ();

फ़ाइल गिटार.जावा:

क्लास गिटार इंप्लीमेंट्स इंस्ट्रूमेंट (@Override public void play() (System.out.println("Play Guitar!"); ))

क्लास गिटार इंप्लीमेंट्स इंस्ट्रूमेंट (

@ ओवरराइड

सार्वजनिक शून्य खेल ()

प्रणाली। बाहर । println ("गिटार बजाओ!");

फ़ाइल ल्यूट.जावा:

पब्लिक क्लास ल्यूट इंप्लीमेंट्स इंस्ट्रूमेंट (@Override public void play() (System.out.println("Play Lute!"); ))

पब्लिक क्लास ल्यूट इंप्लीमेंट्स इंस्ट्रूमेंट (

@ ओवरराइड

सार्वजनिक शून्य खेल ()

प्रणाली। बाहर । println ("प्ले ल्यूट!");

उसके बाद हमने क्लास बदल दी चारणताकि, यदि आवश्यक हो, तो हम कार्यान्वयन को ठीक उसी के साथ बदल सकें जिसकी हमें आवश्यकता है। यह बनाई जा रही प्रणाली में अतिरिक्त लचीलापन लाता है और इसके सामंजस्य (एक दूसरे पर मजबूत वर्ग निर्भरता) को कम करता है।

पब्लिक क्लास बार्ड (निजी इंस्ट्रूमेंट इंस्ट्रूमेंट; पब्लिक बार्ड () () पब्लिक वॉयड प्ले () (इंस्ट्रूमेंट.प्ले ();) पब्लिक वॉयड सेटइंस्ट्रूमेंट (इंस्ट्रूमेंट इंस्ट्रूमेंट) (यह। इंस्ट्रूमेंट = इंस्ट्रूमेंट;))

पब्लिक क्लास बार्ड (

निजी साधन साधन;

2 उत्तर

अच्छा बिंदु - उलटा शब्द कुछ आश्चर्यजनक है (चूंकि डीआईपी लागू करने के बाद, निचले स्तर की निर्भरता मॉड्यूल स्पष्ट रूप से अब उच्च-स्तरीय कॉलर मॉड्यूल पर निर्भर नहीं है: या तो कॉलर या आश्रित अब एक अतिरिक्त अमूर्तता के माध्यम से अधिक शिथिल रूप से युग्मित है )

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

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

संपादन करनाबस स्पष्ट करने के लिए:

"किसी जगह पर मुझे यह भी दिखाई देता है कि इसे निर्भरता उलटा कहा जाता है"

उलटा:एप्लिकेशन से कंटेनर (जैसे स्प्रिंग) में निर्भरता प्रबंधन को उल्टा करें।

निर्भरता इंजेक्शन:

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

नियंत्रण में उलटा (आईओसी) के बारे में क्या?

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

एक डिजाइन गाइड के रूप में नियंत्रण का उलटा निम्नलिखित उद्देश्यों को पूरा करता है:

  • कार्यान्वयन से किसी विशेष कार्य के निष्पादन को अलग करना है।
  • प्रत्येक मॉड्यूल इस बात पर ध्यान केंद्रित कर सकता है कि इसका उद्देश्य क्या है।
  • मॉड्यूल अन्य प्रणालियों के बारे में कोई धारणा नहीं बनाते हैं, लेकिन उनके अनुबंधों पर भरोसा करते हैं।
  • मॉड्यूल को बदलने से अन्य मॉड्यूल प्रभावित नहीं होते हैं।

अधिक जानकारी के लिए देखें।

अंतिम अद्यतन: 03/11/2016

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

शीर्ष स्तर के मॉड्यूल निचले स्तर के मॉड्यूल पर निर्भर नहीं होने चाहिए। दोनों को अमूर्तन पर निर्भर होना चाहिए।

सार विवरण पर निर्भर नहीं होना चाहिए। विवरण अमूर्त पर निर्भर होना चाहिए।

सिद्धांत को समझने के लिए, निम्नलिखित उदाहरण पर विचार करें:

क्लास बुक (सार्वजनिक स्ट्रिंग टेक्स्ट (प्राप्त करें; सेट;) सार्वजनिक कंसोल प्रिंटर प्रिंटर (प्राप्त करें; सेट;) सार्वजनिक शून्य प्रिंट () (प्रिंटर। प्रिंट (टेक्स्ट);)) क्लास कंसोल प्रिंटर (सार्वजनिक शून्य प्रिंट (स्ट्रिंग टेक्स्ट) ( कंसोल। राइटलाइन) (मूलपाठ); ) )

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

आइए अब निम्न-स्तरीय कार्यान्वयन से अमूर्त को अलग करके अपनी कक्षाओं को निर्भरता व्युत्क्रम सिद्धांत के अनुरूप लाने का प्रयास करें:

इंटरफ़ेस आईप्रिंटर (शून्य प्रिंट (स्ट्रिंग टेक्स्ट);) क्लास बुक (सार्वजनिक स्ट्रिंग टेक्स्ट (प्राप्त करें; सेट;) सार्वजनिक आईप्रिंटर प्रिंटर (प्राप्त करें; सेट;) सार्वजनिक पुस्तक (आईपीप्रिंटर प्रिंटर) (यह। प्रिंटर = प्रिंटर;) सार्वजनिक शून्य प्रिंट ( ) (प्रिंटर.प्रिंट (टेक्स्ट);)) क्लास कंसोलप्रिंटर: आईप्रिंटर (सार्वजनिक शून्य प्रिंट (स्ट्रिंग टेक्स्ट) (कंसोल। राइटलाइन ("कंसोल पर प्रिंट करें"); )) क्लास एचटीएमएल प्रिंटर: आईप्रिंटर (सार्वजनिक शून्य प्रिंट (स्ट्रिंग टेक्स्ट) ( कंसोल.राइटलाइन ("एचटीएमएल पर प्रिंट करें"); ))

अब पुस्तक मुद्रण अमूर्त को ठोस कार्यान्वयन से अलग कर दिया गया है। नतीजतन, बुक क्लास और कंसोलप्रिंटर क्लास दोनों ही आईप्रिंटर एब्स्ट्रैक्शन पर निर्भर करते हैं। इसके अलावा, अब हम आईप्रिंटर एब्स्ट्रैक्शन के अतिरिक्त निम्न-स्तरीय कार्यान्वयन भी बना सकते हैं और उन्हें प्रोग्राम में गतिशील रूप से लागू कर सकते हैं:

पुस्तक पुस्तक = नई पुस्तक (नई कंसोलप्रिंटर ()); किताब। प्रिंट (); Book.Printer = नया HtmlPrinter (); किताब। प्रिंट ();

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

जावा छात्रों के साथ कक्षाओं की तैयारी में यह विवरण व्लादिमीर मतवेव के साथ संयुक्त रूप से विकसित किया गया था।

इस श्रृंखला के अन्य लेख:

आइए "निर्भरता" की परिभाषा से शुरू करें। लत क्या है? यदि आपका कोड किसी वर्ग का आंतरिक रूप से उपयोग करता है या स्पष्ट रूप से किसी वर्ग या फ़ंक्शन की स्थिर विधि को कॉल करता है, तो यह एक निर्भरता है। मुझे उदाहरणों के साथ समझाएं:

कक्षा ए के नीचे someMethod () नामक विधि के अंदर स्पष्ट रूप से कक्षा बी का ऑब्जेक्ट बनाता है और इसकी विधि someMethodOfB() तक पहुंचता है

सार्वजनिक वर्ग ए (शून्य कुछ विधि () (बी बी = नया बी (); b.someMethodOfB ();))

इसी तरह, उदाहरण के लिए, क्लास बी सिस्टम क्लास के स्थिर क्षेत्रों और विधियों को स्पष्ट रूप से संदर्भित करता है:

पब्लिक क्लास बी ( void someMethodOfB() (System.out.println("Hello World"); ) )

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

प्रत्यक्ष निर्भरता में क्या गलत है? प्रत्यक्ष निर्भरता खराब है क्योंकि एक वर्ग जो स्वतंत्र रूप से अपने अंदर एक और वर्ग बनाता है वह इस वर्ग से "कसकर" बंधा होता है। वे। अगर यह स्पष्ट रूप से लिखा गया है कि बी = नया बी (); , तो कक्षा A हमेशा कक्षा B के साथ काम करेगी और किसी अन्य वर्ग के साथ नहीं। या अगर यह कहता है System.out.println("..."); तो कक्षा हमेशा System.out पर आउटपुट करेगी और कहीं नहीं।

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

प्रत्यक्ष निर्भरता को इस तरह रेखांकन प्रदर्शित किया जा सकता है:

वे। जब आप अपने कोड में कक्षा ए बनाते हैं: ए ए = नया ए (); वास्तव में, एक वर्ग ए नहीं बनाया गया है, बल्कि आश्रित वर्गों का एक पूरा पदानुक्रम है, जिसका एक उदाहरण ऊपर की तस्वीर में है। यह पदानुक्रम "कठोर" है: अलग-अलग वर्गों के स्रोत कोड को बदले बिना, पदानुक्रम में किसी भी वर्ग को प्रतिस्थापित नहीं किया जा सकता है। इसलिए, इस तरह के कार्यान्वयन में कक्षा ए बदलते परिवेश के लिए खराब रूप से अनुकूल है। सबसे अधिक संभावना है, इसे किसी भी कोड में उपयोग करना संभव नहीं होगा, सिवाय उस विशिष्ट कोड के जिसके लिए आपने इसे लिखा था।

कक्षा ए को विशिष्ट निर्भरताओं से अलग करने के लिए, आवेदन करें निर्भरता इंजेक्शन. निर्भरता इंजेक्शन क्या है? कोड में वांछित वर्ग को स्पष्ट रूप से बनाने के बजाय, निर्भरता को कंस्ट्रक्टर के माध्यम से कक्षा A में पास किया जाता है:

सार्वजनिक वर्ग ए (निजी अंतिम बी बी; सार्वजनिक ए (बी बी) (यह। बी = बी;) सार्वजनिक शून्य कुछ विधि () (बी.someMethodOfB ();))

उस। क्लास ए अब कंस्ट्रक्टर के माध्यम से अपनी निर्भरता प्राप्त करता है। अब, क्लास ए बनाने के लिए, आपको सबसे पहले इसका डिपेंडेंट क्लास बनाना होगा। इस मामले में, यह बी है:

बी बी = नया बी (); ए ए = नया ए (बी); a.someMethod ();

यदि सभी वर्गों के लिए एक ही प्रक्रिया दोहराई जाती है, अर्थात। क्लास डी के कंस्ट्रक्टर को क्लास डी का एक उदाहरण पास करें, क्लास डी के कंस्ट्रक्टर को - इसकी निर्भरता ई और एफ, आदि, फिर आपको कोड मिलेगा, जिसकी सभी निर्भरताएं उल्टे क्रम में बनाई गई हैं:

जी जी = नया जी (); एच एच = नया एच (); एफ एफ = नया (जी, एच); ई ई = नया ई (); डी डी = नया डी (ई, एफ); बी बी = नया बी (डी); ए ए = नया ए (बी); a.someMethod ();

ग्राफिक रूप से, इसे इस तरह प्रदर्शित किया जा सकता है:

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

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

पहली नज़र में निर्भरता इंजेक्शन का नुकसान भी दिखाई देता है - इस पैटर्न का उपयोग करके डिजाइन किए गए वर्गों की वस्तुओं का निर्माण करने के लिए श्रमसाध्य है। इसलिए, निर्भरता इंजेक्शन (उलटा) आमतौर पर इस कार्य को सुविधाजनक बनाने के लिए डिज़ाइन किए गए कुछ पुस्तकालय के संयोजन के साथ प्रयोग किया जाता है। उदाहरण के लिए, Google Guice पुस्तकालयों में से एक। से। मी। ।

© 2022 skudelnica.ru -- प्यार, विश्वासघात, मनोविज्ञान, तलाक, भावनाएं, झगड़े