एक कार्यान्वयन का निर्माण करने वाले बहुरूपिये। DI आशाहीन? सेवा लोकेटर का उपयोग करें?


14

मान लें कि हमारे पास 1001 ग्राहक हैं जो अपनी निर्भरता का निर्माण सीधे स्वीकार इंजेक्शन के बजाय करते हैं। हमारे बॉस के अनुसार 1001 को फिर से भरना एक विकल्प नहीं है। हमें वास्तव में उनके स्रोत तक पहुँचने की अनुमति नहीं है, सिर्फ क्लास की फाइलें।

हम जो करने जा रहे हैं, वह "आधुनिक" है, जो इन 1001 क्लाइंट्स के माध्यम से होता है। हम सभी को पसंद कर सकते हैं। निर्भरताएं उस प्रणाली का हिस्सा हैं। और उनमें से कुछ निर्भरताएँ जिन्हें हम एक नए कार्यान्वयन के लिए बदलने वाले हैं।

हम ग्राहकों की इस भीड़ को संतुष्ट करने के लिए निर्भरता के विभिन्न कार्यान्वयन को कॉन्फ़िगर करने की क्षमता रखते हैं। अफसोस की बात है कि DI एक विकल्प नहीं है क्योंकि ग्राहक कंस्ट्रक्टर या सेटर के साथ इंजेक्शन स्वीकार नहीं करते हैं।

विकल्प:

1) ग्राहकों द्वारा उपयोग की जाने वाली सेवा के कार्यान्वयन को रिफ्लेक्टर करें ताकि यह वह कार्य करे जो अब ग्राहकों को चाहिए। बैंग हम कर रहे हैं। लचीला नहीं है। जटिल नहीं है।

2) कार्यान्वयन को रिफ्लेक्टर करें ताकि यह दर्शाता है कि यह एक और निर्भरता के लिए काम करता है जो इसे एक कारखाने के माध्यम से प्राप्त करता है। अब हम इस बात को नियंत्रित कर सकते हैं कि वे कौन से कार्यान्वयन का उपयोग कारखाने को रिफलेक्ट करके करते हैं।

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

4) कुछ मैंने अभी तक सोचा भी नहीं है।

लक्ष्य:

व्यर्थ की जटिलता को जोड़े बिना पुराने खराब डिज़ाइन किए गए क्लाइंट कोड को भविष्य में खींचकर डिज़ाइन की क्षति को कम करें।

ग्राहकों को अपनी निर्भरता के कार्यान्वयन को जानना या नियंत्रित नहीं करना चाहिए, लेकिन वे उनके साथ निर्माण करने पर जोर देते हैं new। हम नियंत्रण नहीं कर सकते, newलेकिन हम उस वर्ग को नियंत्रित करते हैं जिसका वे निर्माण कर रहे हैं।

मेरा प्रश्न:

मैं क्या विचार करने में असफल रहा?


डॉक्टर ब्राउन से प्रश्न

क्या आपको वास्तव में विभिन्न कार्यान्वयनों के बीच कॉन्फ़िगर करने की संभावना की आवश्यकता है? किस लिए?

चपलता। अनजान लोगों का बहुत। प्रबंधन बदलाव की क्षमता चाहता है। केवल बाहरी दुनिया पर निर्भरता खो देते हैं। परीक्षण भी।

क्या आपको विभिन्न कार्यान्वयनों के बीच स्विच करने के लिए एक रन टाइम मैकेनिक या बस एक संकलन समय मैकेनिक की आवश्यकता है? क्यों?

संकलन समय यांत्रिकी पर्याप्त है। सिवाय परीक्षण के।

कार्यान्वयन के बीच आपको किस ग्रैन्युलैरिटी को स्विच करने की आवश्यकता है? यकायक? प्रति मॉड्यूल (प्रत्येक वर्ग के एक समूह से युक्त)? प्रति वर्ग?

1001 में से केवल एक ही समय में सिस्टम के माध्यम से चलाया जाता है। सभी ग्राहक जो एक बार में उपयोग करते हैं, उन्हें बदलना संभव है। हालांकि निर्भरता का व्यक्तिगत नियंत्रण महत्वपूर्ण है।

स्विच को नियंत्रित करने की आवश्यकता किसे है? केवल आपकी / आपकी डेवलपर टीम? एक प्रशासक? प्रत्येक ग्राहक अपने दम पर? या ग्राहक के कोड के लिए रखरखाव डेवलपर्स? तो मैकेनिक होने के लिए कितना आसान / मजबूत / मूर्ख है?

परीक्षण के लिए देव। बाहरी हार्डवेयर निर्भरता के रूप में व्यवस्थापक बदलते हैं। इसे परीक्षण और कॉन्फ़िगर करना आसान होना चाहिए।


हमारा लक्ष्य यह दिखाना है कि प्रणाली को जल्दी और आधुनिक बनाया जा सकता है।


कार्यान्वयन स्विच के लिए वास्तविक उपयोग का मामला?

एक है, हार्डवेयर समाधान तैयार होने तक कुछ डेटा सॉफ्टवेयर द्वारा प्रदान किया जाएगा।


1
मुझे नहीं लगता कि आप वैश्विक राज्य में कारखानों या लोकेटरों का भंडारण करके बहुत कुछ हासिल करेंगे। क्यों परेशान? क्या आप ग्राहकों पर निर्भरता का परीक्षण करने जा रहे हैं?
बसिलेव

कस्टम क्लास लोडर का उपयोग करने पर विचार करें।
बासिलेव

जिज्ञासा से बाहर, यह प्रणाली क्या है?
प्राइम

जवाबों:


7

ठीक है, मुझे यकीन नहीं है कि मैं आपके समर्थित समाधानों के तकनीकी विवरणों और उनके सटीक अंतरों को पूरी तरह से समझता हूं, लेकिन IMHO आपको पहले यह पता लगाना होगा कि आपको वास्तव में किस तरह के लचीलेपन की आवश्यकता है।

जो सवाल आपको खुद से पूछना है वो हैं:

  • क्या आपको वास्तव में विभिन्न कार्यान्वयनों के बीच कॉन्फ़िगर करने की संभावना की आवश्यकता है? किस लिए?

  • क्या आपको विभिन्न कार्यान्वयनों के बीच स्विच करने के लिए एक रन टाइम मैकेनिक या बस एक संकलन समय मैकेनिक की आवश्यकता है? क्यों?

  • कार्यान्वयन के बीच आपको किस ग्रैन्युलैरिटी को स्विच करने की आवश्यकता है? यकायक? प्रति मॉड्यूल (प्रत्येक वर्ग के एक समूह से युक्त)? प्रति वर्ग?

  • स्विच को नियंत्रित करने की आवश्यकता किसे है? केवल आपकी / आपकी डेवलपर टीम? एक प्रशासक? प्रत्येक ग्राहक अपने दम पर? या ग्राहक के कोड के लिए रखरखाव डेवलपर्स? तो मैकेनिक होने के लिए कितना आसान / मजबूत / मूर्ख है?

इन सवालों के जवाब को ध्यान में रखते हुए, सबसे सरल समाधान आप सोच सकते हैं जो आपको आवश्यक लचीलापन प्रदान करता है। किसी भी लचीलेपन को लागू न करें जो आपको "सिर्फ मामले में" के बारे में सुनिश्चित नहीं है अगर इसका मतलब अतिरिक्त प्रयास है।

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


अच्छे सवाल! कृपया अपडेट देखें।
कैंडिड_ऑरेंज

वास्तविक उपयोग के मामले के साथ अद्यतन किया गया।
कैंडिड_ऑरेंज

@CandiedOrange: मैं आपको कुछ मछली नहीं दे सकता, मैं केवल आप अपने आप को द्वारा मछली पकड़ने में मदद करने के :-) कोशिश कर सकते हैं
डॉक ब्राउन

समझ लिया। अगर मैं बेहतर चारा या एक अलग मछली पकड़ने के छेद की जरूरत है, तो मैं सिर्फ पानी में घूर रहा हूं। मुझे उचित DI करना पसंद है, लेकिन यह स्थिति इसके लिए अनुमति नहीं देती है।
कैंडिड_ऑरेंज

1
@CandiedOrange DI करने की इच्छा पर लटका नहीं है क्योंकि यह "अच्छा" या "बेहतर" है और कुछ भी नहीं है। DI एक समस्या का एक विशेष समाधान है (या कभी-कभी कई)। लेकिन, यह हमेशा सबसे "फिट" समाधान नहीं है। इसके साथ प्यार में मत पड़ो ... जैसा है वैसा ही समझो। यह एक उपकरण है।
18

2

बस यह सुनिश्चित करने के लिए कि मुझे यह अधिकार मिल रहा है। आपके पास कुछ वर्गों से बनी कुछ सेवा, कहते हैं C1,...,Cnऔर ग्राहकों का एक समूह है जो सीधे कॉल करते हैं new Ci(...)। इसलिए मुझे लगता है कि मैं आपके समाधान की सामान्य संरचना से सहमत हूं, जो कुछ नई कक्षाओं के साथ एक नई आंतरिक सेवा बनाने के लिए है जो D1,...,Dnअच्छी और आधुनिक हैं और उनकी निर्भरता को इंजेक्ट करते हैं (स्टैक के माध्यम से इस तरह की निर्भरता की अनुमति देते हैं) और फिर Ciकुछ भी नहीं करने के लिए फिर से लिखना और तुरंत लिखना करने के लिए Di। सवाल यह कैसे करना है और आप में कुछ तरीके का सुझाव दिया है 2और 3

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

public class OldClassI {
    private final NewClassI newImplementation;

    public OldClassI(Object parameter) {
        this.newImplementation = CompositionRoot.getInstance().getNewClassI(parameter);
    }
}

अनिवार्य रूप से यह आपका समाधान 2 है, लेकिन यह आपके सभी कारखानों को एक स्थान पर एकत्रित करता है, बाकी निर्भरता इंजेक्शन के साथ।


मैं इससे सहमत हु। बस यह सुनिश्चित नहीं करें कि यह विकल्प 3 से सेवा लोकेटर के समान कैसे नहीं है। क्या आप प्रत्येक कॉल के साथ एक नया उदाहरण बनाने की उम्मीद कर रहे हैं getInstance()?
कैंडिड_ओरेंज

@CandiedOrange यह संभवत: उपयोग में सिर्फ एक झड़प है, मेरे लिए एक सेवा लोकेटर विशेष रूप से कुछ ऐसा है जो अनिवार्य रूप से प्रकारों से वस्तुओं के लिए एक हैशमैप है, जबकि यह रचना जड़ अन्य वस्तुओं के निर्माण के तरीकों का एक समूह है।
15

1

सरल, कुछ भी नहीं फैंसी, विलक्षण कार्यान्वयन के साथ शुरू करें।

यदि आपको बाद में अतिरिक्त कार्यान्वयन बनाने की आवश्यकता है, तो यह एक सवाल है कि कार्यान्वयन निर्णय कब होता है।

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

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

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