क्या कोई प्रोग्रामिंग भाषा मौजूद है जो विशेष रूप से निर्भरता इंजेक्शन के लिए डिज़ाइन की गई है?


21

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

क्या कोई ऐसी भाषा है जिसे विशेष रूप से निर्भरता इंजेक्शन को आसान बनाने के लिए डिज़ाइन किया गया है, और इसके विपरीत, छिपी निर्भरता को कठिन बनाना है?

स्पष्टीकरण:

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

मैं एक भाषा की सिफारिश के लिए नहीं देख रहा हूँ। यह एक ऐतिहासिक सवाल है। क्या किसी भी भाषा के लेखक ने ऐसा करने के लिए स्पष्ट रूप से निर्धारित किया है?


1
दृढ़ता से संबंधित, अगर एकमुश्त डुप्लिकेट नहीं: भाषा में निर्भरता इंजेक्शन कैसे एकीकृत किया जा सकता है?
रॉबर्ट हार्वे

व्ही! 3K! अब मैं इस प्रश्न को बंद करने के लिए उन्हें वोट देते हुए देख सकता हूं। :) वोट के लिए धन्यवाद।
कैंडिड_ऑरेंज

1
आपको वैसे भी वह पोस्ट पढ़नी चाहिए। "क्या यह मौजूद है" एक बहुत ही कम दिलचस्प सवाल है, जब तक कि आप इसे कुछ इस तरह से विस्तारित न करें कि "उन्होंने यह कैसे किया?"
रॉबर्ट हार्वे

1
हास्केल की गिनती होगी? करी और उच्च-क्रम के कार्यों से आप ज्यादातर ऐसी समस्याओं को हल कर सकते हैं जिन्हें DI आमतौर पर OOP भाषाओं में हल करता है और शुद्धता पर इसकी सख्ती के साथ आपको IO आदि जैसे साइडइफ़ेक्ट्स को अलग करने के लिए मजबूर किया जाता है और फ़ंक्शंस जादुई रूप से कुछ ऐसा नहीं कर सकते हैं कि वे एक तर्क के रूप में पारित हो गए थे। आपको कॉन्फ़िगरेशन पर कोई सम्मेलन नहीं मिलता है, लेकिन दूसरी तरफ मैं धीरे-धीरे उस ओर से दूर जा रहा हूं, यहां तक ​​कि आजकल मेरे ओओपी कोड में भी मैंने देखा है कि अधिकांश टीमों को मध्यम आकार की परियोजनाओं और बड़े पर भरोसा नहीं किया जा सकता है।
१३

1
@wasatz: हाँ, हास्केल मायने रखता है। अधिकांश "सॉफ़्टवेयर पैटर्न" वास्तव में प्रोग्रामिंग भाषा में कमियों के लिए सिर्फ वर्कअराउंड हैं।
रॉबर्ट हार्वे

जवाबों:


21

हाँ, वास्तव में है। की तरह।

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

इसलिए, भाषा को DI के लिए डिज़ाइन नहीं किया गया है, बल्कि DI के लिए आवश्यकता भाषा डिज़ाइन का परिणाम है।

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

आप एक स्ट्रिंग चाहते हैं? ठीक है, आपको पहले कक्षा stdlibको सौंपने के लिए ऑब्जेक्ट पूछना होगा String। ओह, लेकिन आप कैसे पहुँच सकते हैं stdlib? ठीक है, आपको पहले वस्तु platformको सौंपने के लिए कहना होगा stdlib। ओह, लेकिन आप कैसे पहुँच सकते हैं platform? ठीक है, आपको सबसे पहले किसी और से आपको platformवस्तु सौंपने के लिए कहना होगा । ओह, लेकिन आप कैसे किसी के लिए उपयोग करते हैं? ठीक है, आपको पहले किसी और से पूछना होगा कि वह वस्तु आपको सौंप दे।

यह खरगोश के छेद से कितना नीचे जाता है? पुनरावृत्ति कहाँ रुकती है? सभी तरह से, वास्तव में। यह बंद नहीं करता है। फिर, आप समाचार पत्र में एक कार्यक्रम कैसे लिख सकते हैं? ठीक है, सख्ती से बोल, तुम नहीं कर सकते!

आपको कुछ बाहरी इकाई की आवश्यकता होती है जो इसे एक साथ जोड़ती है। समाचारपत्र में, वह संस्था आईडीई है। आईडीई पूरे कार्यक्रम को देखता है। यह एक साथ टुकड़े टुकड़े तार कर सकते हैं। समाचारपत्र में मानक पैटर्न यह है कि आपके आवेदन के केंद्रीय वर्ग में एक platformएक्सेसर कहा जाता है , और समाचार पत्र आईडीई उस एक्सेसर में एक वस्तु को इंजेक्ट करता है जिसमें ऐसी विधियाँ होती हैं जो प्रोग्रामिंग की कुछ मूलभूत आवश्यकताओं को वापस करती हैं: एक Stringवर्ग, एक Numberवर्ग, एक Arrayवर्ग और इसी तरह।

यदि आप अपने आवेदन का परीक्षण करना चाहते हैं, तो आप उस platformऑब्जेक्ट को इंजेक्ट कर सकते हैं, जिसकी Fileविधि डमी विधियों के साथ एक वर्ग लौटाती है। यदि आप अपने एप्लिकेशन को क्लाउड पर तैनात करना चाहते हैं, तो आप एक ऐसे प्लेटफ़ॉर्म को इंजेक्ट करते हैं जिसका Fileवर्ग वास्तव में अमेज़ॅन S3 द्वारा समर्थित है। क्रॉस-प्लेटफ़ॉर्म GUI विभिन्न OSI के लिए अलग-अलग GUI फ्रेमवर्क को इंजेक्ट करके काम करते हैं। समाचारपत्र में एक प्रयोगात्मक समाचार पत्र-से-ईसीएमस्क्रिप्ट कंपाइलर और HTML-समर्थित GUI फ्रेमवर्क है, जो आपको अलग-अलग GUI तत्वों को इंजेक्ट करके, बिना किसी बदलाव के ब्राउज़र में देशी डेस्कटॉप से ​​पूरी तरह से चित्रित GUI एप्लिकेशन को पोर्ट करने की अनुमति देता है।

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

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

class Foo extends Bar // using Java syntax for familiarity

या, समाचार पत्र में:

class Foo = Bar () () : ()

जावा में, यह Fooस्थिर वैश्विक नामस्थान में एक नाम बनाएगा , और Barस्थैतिक वैश्विक नामस्थान में ऊपर की ओर दिखेगा Bar Foo। रूबी में भी, जो बहुत अधिक गतिशील है, यह अभी भी वैश्विक नाम स्थान में एक स्थिर स्थिरांक बनाएगा।

समाचारपत्र में, समतुल्य घोषणा का अर्थ है: नाम के लिए एक गेट्टर विधि बनाएं Fooऔर इसे एक ऐसा वर्ग लौटाएं जो नाम के तरीके को कॉल करके अपने सुपरक्लास को देखता है Bar। नोट: यह रूबी की तरह नहीं है, जहां आप किसी भी निष्पादन योग्य रूबी कोड को सुपरक्लास घोषणा के रूप में डाल सकते हैं , लेकिन कोड को केवल एक बार निष्पादित किया जाएगा जब कक्षा बनाई जाती है और उस कोड का वापसी मूल्य निर्धारित सुपरक्लास बन जाता है। नहीं। विधि Barको हर एक विधि देखने के लिए कहा जाता है !

इसके कुछ गहरा प्रभाव हैं:

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

    class Outer {
      class Inner { /* … */ }
    }
    
    class Sub extends Outer {
      override class Inner { /* … */ }
    }
    

    Newspeak:

    class Outer = () (
      class Inner = () () : ()
    ) : ()
    
    class Sub = Outer () (
      class Inner = () () : ()
    ) : ()
    
  • चूँकि सुपरक्लास सिर्फ एक विधि कॉल है जो एक वर्ग को लौटाता है, आप उस विधि को बाहरी वर्ग के उपवर्ग में ओवरराइड कर सकते हैं, सुपरक्लास में परिभाषित आंतरिक वर्ग उपवर्ग में एक अलग सुपरक्लास हो सकता है। आप मुफ्त में श्रेणी पदानुक्रम विरासत प्राप्त करते हैं:

    class Outer {
      class MyCoolArray extends Array { /* … */ }
    }
    
    class Sub extends Outer {
      override class Array { /* … */ }
      // Now, for instances of `Sub`, `MyCoolArray` has a different superclass 
      // than for instances of `Outer`!!!
    }
    

    Newspeak:

    class Outer = () (
      class MyCoolArray = Array () () : ()
    ) : ()
    
    class Sub = Outer () (
      class Array = () () : ()
    ) : ()
    
  • और अंत में, इस चर्चा के लिए सबसे महत्वपूर्ण: चूंकि (उन लोगों के अलावा, जिन्हें आपने अपनी कक्षा में परिभाषित किया है, स्पष्ट रूप से) आप केवल अपने शाब्दिक रूप से संलग्न वर्ग (एस) और अपने सुपरक्लास (एस) में तरीकों को कॉल कर सकते हैं, एक शीर्ष स्तर का बाहरी वर्ग स्पष्ट रूप से इंजेक्ट किए गए लोगों को छोड़कर किसी भी तरीके को कॉल नहीं कर सकते हैं: एक शीर्ष-स्तरीय वर्ग के पास एक संलग्न वर्ग नहीं है, जिसके तरीकों को यह कॉल कर सकता है, और इसमें डिफ़ॉल्ट के अलावा कोई सुपरक्लास नहीं हो सकता है, क्योंकि सुपरक्लास घोषणा है विधि कॉल, और यह स्पष्ट रूप से सुपरक्लास में नहीं जा सकता (यह है)सुपरक्लास) और यह भी शाब्दिक रूप से संलग्न वर्ग में नहीं जा सकता है, क्योंकि कोई भी नहीं है। इसका मतलब यह है कि शीर्ष स्तर की कक्षाएं पूरी तरह से समाप्त हो जाती हैं, वे केवल वही एक्सेस कर सकते हैं जो उन्हें स्पष्ट रूप से इंजेक्ट किया जाता है, और वे केवल वे इंजेक्शन लगाते हैं जो वे स्पष्ट रूप से पूछते हैं। दूसरे शब्दों में: शीर्ष-स्तरीय कक्षाएं मॉड्यूल हैं। आपको मुफ्त में एक पूरा मॉड्यूल सिस्टम मिलता है। वास्तव में, अधिक सटीक होना: शीर्ष-स्तरीय कक्षाएं मॉड्यूल घोषणाएं हैं, इसके उदाहरण मॉड्यूल हैं। तो, आप पैरामीट्रिक मॉड्यूल घोषणाओं और मुक्त करने के लिए प्रथम श्रेणी के मॉड्यूल के साथ एक मॉड्यूल प्रणाली प्राप्त करते हैं, कुछ, जो बहुत परिष्कृत, मॉड्यूल सिस्टम भी कर सकते हैं।

इस सभी इंजेक्शन को दर्द रहित बनाने के लिए, कक्षा की घोषणाओं में एक असामान्य संरचना होती है: इनमें दो घोषणाएँ होती हैं। एक वर्ग रचनाकार है, जो वह निर्माता नहीं है जो वर्ग के उदाहरणों का निर्माण करता है , बल्कि वह निर्माणकर्ता जो उस वातावरण का निर्माण करता है जिसमें वर्ग निकाय चलता है। जावा-जैसे सिंटैक्स में, यह कुछ इस तरह दिखेगा:

class Foo(platform) extends Bar {
  Array  = platform.collections.Array
  String = platform.lang.String
  File   = platform.io.File
| // separator between class constructor and class body
  class MyArray extends Array { /* … */ }
  // Array refers to the method defined above which in turn gets it from the 
  // platform object that was passed into the class "somehow"
}

Newspeak:

class Foo using: platform = Bar (
  Array = platform collections Array
  String = platform streams String 
  File = platform files ExternalReadWriteStream
) (
  class MyArray = Array () () : ()
) : ()

ध्यान दें कि जिस तरह से एक समाचार पत्र प्रोग्रामर वास्तव में कक्षा को देखने जा रहा है, वह इस तरह है:समाचार पत्र IDE कई नेस्टेड वर्गों को प्रदर्शित करता है

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

लेकिन वास्तव में, आपको इसके साथ खेलना होगा। यह सभी मुख्य धारा और यहां तक ​​कि सबसे गैर-मुख्यधारा भाषाओं से इतना अलग है कि इसे समझाना मुश्किल है, इसका अनुभव करना होगा।


3
भावहीन। स्थिर राज्य और वैश्विक राज्य के उपयोग को मना करें, और आप लगभग किसी भी आधुनिक प्रोग्रामिंग भाषा के बारे में यह कह सकते हैं।
रॉबर्ट हार्वे

जिज्ञासु, मेरे हाथ से बने कई इंजेक्शन कंटेनर स्थिर कारखाने हैं। इससे पहले कि एक बुरी चीज के रूप में नहीं सोचा था।
कैंडिड_ऑरेंज

@ Jörg किसी भी तरह से आप इस जवाब को थोड़ा और अधिक कर सकते हैं? मैं "googled" न्यूजपेक्लांग भाषा निर्भरता इंजेक्शन "और खाली आया हूँ। निकटतम चीज़ जो मुझे मिल सकती है वह यह थी: news.ycombinator.com/item?id=9620561
candied_orange

@ कंडिडऑरेन्ज: मैं उत्तर का विस्तार करने की प्रक्रिया में था, लेकिन तब "वास्तविक दुनिया" ने हस्तक्षेप किया। क्या वो बेहतर है?
जॉर्ग डब्ल्यू मित्तग

3
@ JörgWMittag पवित्र बकवास! खैर यह निश्चित रूप से "अधिक" है। जब मैं "बेहतर" का मूल्यांकन करता हूं, तो रुको। इसके माध्यम से प्राप्त करने के लिए बाथरूम की यात्रा की शक्ति की आवश्यकता हो सकती है।
कैंडिड_ऑरेंज

7

वेक प्रोग्रामिंग लैंग्वेज निर्भरता इंजेक्शन का उपयोग करने के लिए डिज़ाइन की गई है। मूल रूप से, यह भाषा में पके हुए एक निर्भरता इंजेक्शन ढांचे के बराबर है। कक्षाएं उन मापदंडों को परिभाषित करती हैं जो वे needऔर provideकंपाइलर सब कुछ हुक करते हैं।


6

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

public interface I {
    void something ();
)

public class Concrete implements I {
    public void something () { ... }
}

public class Client {
    I myI;
    public Client (I injected) { myI = injected; }
    ...
}

...

    Client c = new Client (new Concrete());
    ...

और ग्राहक और उसके उपयोग की जगह:

public class Client {
   I myI = new I();
   ...
}

   Client c = new Client { I -> Concrete } ();

ध्यान दें कि यह सृजन के बजाय एक निर्भरता के उपयोग के बिंदु को सरल करता है। यह हमें फ़ैक्टरी पैटर्न से बचने की भी अनुमति देता है (जब भी हम चाहते हैं एक नई मांग पर बनाया जा सकता है)।


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

0

मैंने इसका उपयोग नहीं किया है, लेकिन प्लास्टिक प्रोग्रामिंग भाषा की आधिकारिक टैगलाइन है " क्या होता है अगर आप निर्भरता इंजेक्शन लेते हैं और इसे प्रोग्रामिंग भाषा में सेंकते हैं? "। यह काफी दिलचस्प लगता है

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.