क्या ServiceLocator एक प्रतिमान है?


137

हाल ही में मैंने मार्क सेमन के लेख को सर्विस लोकेटर विरोधी पैटर्न के बारे में पढ़ा है ।

लेखक दो मुख्य कारणों के बारे में बताता है कि ServiceLocator एक प्रतिमान क्यों है:

  1. एपीआई उपयोग की समस्या (जो कि मैं पूरी तरह से ठीक हूं)
    जब क्लास एक सेवा लोकेटर को नियुक्त करती है तो इसकी निर्भरता को देखना बहुत कठिन होता है, ज्यादातर मामलों में, क्लास में केवल एक PARAMETERLESS कंस्ट्रक्टर होता है। ServiceLocator के विपरीत, DI दृष्टिकोण स्पष्ट रूप से निर्माणकर्ता के मापदंडों के माध्यम से निर्भरता को उजागर करता है, ताकि इंटेलीजेंसी में निर्भरता आसान दिखाई दे।

  2. रखरखाव का मुद्दा (जो मुझे पहेलियाँ)
    निम्नलिखित विस्तार पर विचार करें

हमारे पास एक वर्ग 'MyType' है जो सेवा लोकेटर दृष्टिकोण को नियोजित करता है:

public class MyType
{
    public void MyMethod()
    {
        var dep1 = Locator.Resolve<IDep1>();
        dep1.DoSomething();
    }
}

अब हम 'MyType' श्रेणी में एक और निर्भरता जोड़ना चाहते हैं

public class MyType
{
    public void MyMethod()
    {
        var dep1 = Locator.Resolve<IDep1>();
        dep1.DoSomething();

        // new dependency
        var dep2 = Locator.Resolve<IDep2>();
        dep2.DoSomething();
    }
}

और यहीं से मेरी गलतफहमी शुरू होती है। लेखक कहता है:

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

लेकिन एक सेकंड रुको, अगर हम DI दृष्टिकोण का उपयोग कर रहे थे, तो हम कंस्ट्रक्टर में एक अन्य पैरामीटर के साथ निर्भरता का परिचय देंगे (निर्माण इंजेक्शन के मामले में)। और समस्या तब भी रहेगी। यदि हम ServiceLocator को सेटअप करना भूल सकते हैं, तो हम अपने IoC कंटेनर में नया मैपिंग जोड़ना भूल सकते हैं और DI दृष्टिकोण से समान रन-टाइम समस्या होगी।

इसके अलावा, लेखक ने इकाई परीक्षण कठिनाइयों के बारे में उल्लेख किया है। लेकिन, क्या हमारे पास DI दृष्टिकोण के साथ कोई समस्या नहीं है? क्या हमें उन सभी परीक्षणों को अद्यतन करने की आवश्यकता नहीं है जो उस वर्ग को त्वरित कर रहे थे? हम उन्हें केवल हमारे परीक्षण को अनिवार्य बनाने के लिए एक नए नकली निर्भरता को पारित करने के लिए अद्यतन करेंगे। और मुझे उस अपडेट और समय बिताने से कोई लाभ नहीं दिखता है।

मैं सेवा लोकेटर दृष्टिकोण का बचाव करने की कोशिश नहीं कर रहा हूं। लेकिन इस गलतफहमी से मुझे लगता है कि मैं बहुत महत्वपूर्ण कुछ खो रहा हूं। क्या कोई मेरा संदेह दूर कर सकता है?

अद्यतन (सारांश):

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

और यहाँ मुख्य अंतर हैं जिन्होंने मुझे अपनी नई परियोजनाओं के लिए सेवा लोकेटर का उपयोग नहीं करने के लिए आश्वस्त किया:

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

विवरण के लिए उत्कृष्ट उत्तर पढ़ें जो नीचे दिए गए हैं।


"क्या हमें उन सभी परीक्षणों को अद्यतन करने की आवश्यकता नहीं है जो उस वर्ग को त्वरित कर रहे थे?" जरूरी नहीं कि आप अपने परीक्षणों में किसी बिल्डर का उपयोग कर रहे हों। इस मामले में आपको केवल बिल्डर को अपडेट करना होगा।
पीटर कर्ल्ससन

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

1
ध्यान दें कि जब से यह प्रश्न पोस्ट किया गया है, मार्क सेमैन की सर्विस लोकेटर पर एक अपडेट है, एक एंटी-पैटर्न पोस्ट है जिसमें वर्णन किया गया है कि सर्विस लोकेटर कैसे एनओपी को तोड़कर ओओपी का उल्लंघन करता है, जो कि उसका सबसे अच्छा तर्क है (और सभी लक्षणों के लिए अंतर्निहित कारण वह सभी पूर्व तर्कों में इस्तेमाल किया)। अद्यतन 2015-10-26: सेवा लोकेटर के साथ मूलभूत समस्या यह है कि यह इनकैप्सुलेशन का उल्लंघन करता है
नाइटऑवल 88

जवाबों:


125

यदि आप प्रतिमानों को केवल प्रतिमानों के रूप में परिभाषित करते हैं क्योंकि कुछ स्थितियाँ ऐसी हैं जहाँ यह फिट नहीं होती है, तो हाँ यह एक विरोधी प्रतिमान है। लेकिन उस तर्क के साथ सभी पैटर्न विरोधी पैटर्न भी होंगे।

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

public class MyType
{
    public void MyMethod()
    {
        var dep1 = Locator.Resolve<IDep1>();
        dep1.DoSomething();

        // new dependency
        var dep2 = Locator.Resolve<IDep2>();
        dep2.DoSomething();
    }
}

उस वर्ग के साथ रखरखाव दुःस्वप्न यह है कि निर्भरताएं छिपी हुई हैं। यदि आप उस वर्ग को बनाते हैं और उसका उपयोग करते हैं:

var myType = new MyType();
myType.MyMethod();

आप यह नहीं समझते कि यह निर्भरता है यदि वे सेवा स्थान का उपयोग करके छिपे हुए हैं। अब, अगर हम इसके बजाय निर्भरता इंजेक्शन का उपयोग करते हैं:

public class MyType
{
    public MyType(IDep1 dep1, IDep2 dep2)
    {
    }

    public void MyMethod()
    {
        dep1.DoSomething();

        // new dependency
        dep2.DoSomething();
    }
}

आप सीधे आश्रितों को हाजिर कर सकते हैं और उन्हें संतुष्ट करने से पहले कक्षाओं का उपयोग नहीं कर सकते।

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

क्या पैटर्न एक पैटर्न विरोधी है?

नहीं।

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

लेकिन एक बेहतर उदाहरण ASP.NET MVC और WebApi है। क्या आपको लगता है कि नियंत्रकों में निर्भरता इंजेक्शन संभव बनाता है? यह सही है - सेवा स्थान।

आपके सवाल

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

दो और गंभीर समस्याएं हैं:

  1. सेवा स्थान के साथ आप एक और निर्भरता भी जोड़ रहे हैं: सेवा लोकेटर।
  2. आप कैसे बता सकते हैं कि जीवनकाल किन निर्भरताओं में होना चाहिए, और कैसे / कब उन्हें साफ करना चाहिए?

कंस्ट्रक्टर इंजेक्शन के साथ एक कंटेनर का उपयोग करके जो आपको मुफ्त में मिलता है।

यदि हम ServiceLocator को सेटअप करना भूल जाते हैं, तो हम अपने IoC कंटेनर में नया मैपिंग जोड़ना भूल सकते हैं और DI दृष्टिकोण से समान रन-टाइम समस्या होगी।

यह सच है। लेकिन कंस्ट्रक्टर इंजेक्शन के साथ आपको यह पता लगाने के लिए पूरी कक्षा को स्कैन करने की आवश्यकता नहीं है कि कौन सी निर्भरता गायब है।

और कुछ बेहतर कंटेनर स्टार्टअप (सभी कंस्ट्रक्टर को स्कैन करके) पर निर्भरता को भी मान्य करते हैं। तो उन कंटेनरों के साथ आपको सीधे रनटाइम त्रुटि मिलती है, न कि कुछ बाद के अस्थायी बिंदु पर।

इसके अलावा, लेखक ने इकाई परीक्षण कठिनाइयों के बारे में उल्लेख किया है। लेकिन, क्या हमारे पास DI दृष्टिकोण के साथ कोई समस्या नहीं है?

जैसा कि आपके पास स्थैतिक सेवा लोकेटर पर निर्भरता नहीं है। क्या आपने स्थैतिक निर्भरता के साथ समानांतर परीक्षण करने की कोशिश की है? यह मज़ाक नहीं है।


2
Jgauffin, आपके उत्तर के लिए धन्यवाद। आपने स्टार्टअप पर ऑटो चेक के बारे में एक महत्वपूर्ण बात बताई। मैं उस के बारे में नहीं सोच रहा था और अब मुझे DI का एक और फायदा दिखाई दे रहा है। आपने एक उदाहरण भी दिया: "var myType = new MyType ()"। लेकिन मैं इसे एक वैध के रूप में नहीं गिना सकता क्योंकि हम कभी भी किसी वास्तविक ऐप में निर्भरता को कम नहीं करते हैं (IoC कंटेनर हमारे लिए हर समय ऐसा करता है)। Ie: MVC ऐप में हमारे पास एक नियंत्रक है, जो IMyService पर निर्भर करता है और MyServiceImpl IMyRepository पर निर्भर करता है। हम कभी भी MyRepository और MyService को नहीं देख पाएंगे। हमें Ctor params (जैसे ServiceLocator) से उदाहरण मिलते हैं और उनका उपयोग करते हैं। क्या हम नहीं?
दाविदॉफ़

33
सेवा लोकेटर के लिए आपका एकमात्र तर्क एक विरोधी पैटर्न नहीं है: "नियंत्रण कंटेनरों का व्युत्क्रम सेवा स्थान के बिना काम नहीं करेगा"। यह तर्क हालांकि अमान्य है, क्योंकि सेवा लोकेटर इरादों के बारे में है और यांत्रिकी के बारे में नहीं है, जैसा कि मार्क सेमन द्वारा यहां स्पष्ट रूप से समझाया गया है: "एक कंपोजिट रूट में एनैप्ड डीआई कंटेनर सेवा लोकेटर नहीं है - यह एक बुनियादी ढांचा घटक है।"
स्टीवन

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

1
मैं यह बताना चाहता हूं कि यह आम तौर पर अच्छा जवाब है, मैंने सिर्फ आपके द्वारा किए गए एक भ्रामक बिंदु पर टिप्पणी की है।
सुमेरे

2
@jgauffin DI और SL दोनों ही आईओसी के संस्करण हैं। SL इसे करने का गलत तरीका है। एक IoC कंटेनर SL हो सकता है, या यह DI का उपयोग कर सकता है। यह इस पर निर्भर करता है कि यह कैसे वायर्ड है। लेकिन SL खराब है, बुरा खराब है। यह इस तथ्य को छिपाने का एक तरीका है कि आप सब कुछ एक साथ कसकर कर रहे हैं।
दर्पण

37

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

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


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

रे: "जब आप विरासत कोड के साथ काम कर रहे होते हैं, तो आपको उस गंदगी से बाहर निकालने के लिए सब कुछ उचित होता है" कभी-कभी मुझे आश्चर्य होता है कि क्या केवल विरासत कोड का थोड़ा सा ही अस्तित्व है, लेकिन क्योंकि हम इसे ठीक करने के लिए कुछ भी कर सकते हैं किसी तरह कभी ऐसा करने में कामयाब नहीं हुआ।
ड्रू डेलानो

8

परीक्षण के दृष्टिकोण से, सेवा लोकेटर खराब है। मिसको हेवरी की गूगल टेक टॉक कोड उदाहरणों के साथ अच्छी व्याख्या http://youtu.be/RlfLCWKxHJ0 मिनट 8:45 मिनट पर शुरू करें। मुझे उनकी उपमा पसंद आई: यदि आपको $ 25 की आवश्यकता है, तो अपने बटुए को देने के बजाय सीधे पैसे माँगें जहाँ से पैसा लिया जाएगा। वह सेवा लोकेटर की तुलना एक ऐसी हाइस्टैक से करता है जिसमें आपको सुई की आवश्यकता होती है और इसे पुनर्प्राप्त करना जानता है। सेवा लोकेटर का उपयोग करने वाली कक्षाएं इसके कारण पुन: उपयोग करने के लिए कठिन हैं।


10
यह एक पुनर्नवीनीकरण राय है और टिप्पणी के रूप में बेहतर होगा। इसके अलावा, मुझे लगता है कि आपके (उनके?) सादृश्य यह साबित करने के लिए कार्य करते हैं कि कुछ पैटर्न दूसरों पर कुछ समस्याओं के लिए अधिक उपयुक्त हैं।
8bitjunkie

6

रखरखाव का मुद्दा (जो मुझे पहेलियाँ)

सेवा लोकेटर का उपयोग इस संबंध में खराब होने के 2 अलग-अलग कारण हैं।

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

सादा और सरल: इसमें सेवा लोकेटर वाला एक वर्ग एक से अधिक पुन: उपयोग करना मुश्किल है जो इसके निर्माता के माध्यम से अपनी निर्भरता स्वीकार करता है।

उस मामले पर विचार करें जहां आपको किसी सेवा का उपयोग करने की आवश्यकता है LibraryA उसServiceLocatorA , LibraryBजिसका लेखक ने फैसला किया है और वह सेवा जिसका लेखक ने निर्णय लिया है, का उपयोग करेगा ServiceLocatorB। हमारे पास अपने प्रोजेक्ट में 2 अलग-अलग सर्विस लोकेटर का उपयोग करने के अलावा कोई विकल्प नहीं है। अगर हमें अच्छे डॉक्यूमेंटेशन, सोर्स कोड या स्पीड डायल पर लेखक नहीं है, तो कितने निर्भरता को कॉन्फ़िगर करने की आवश्यकता है, यह एक अनुमान लगाने का खेल है। इन विकल्पों को नाकाम करते हुए, हमें बस एक डिकम्पॉइलर का उपयोग करने की आवश्यकता हो सकती हैयह जानने के लिए कि निर्भरताएं क्या हैं। हमें 2 पूरी तरह से अलग सेवा लोकेटर एपीआई को कॉन्फ़िगर करने की आवश्यकता हो सकती है, और डिजाइन के आधार पर, यह संभव नहीं है कि आप अपने मौजूदा डीआई कंटेनर को लपेटें। दो पुस्तकालयों के बीच निर्भरता के एक उदाहरण को साझा करना बिल्कुल भी संभव नहीं होगा। परियोजना की जटिलता और भी जटिल हो सकती है यदि सेवा लोकेटर वास्तव में उसी पुस्तकालयों में निवास नहीं करते हैं, जिस तरह की सेवाओं की हमें आवश्यकता होती है - हम अतिरिक्त पुस्तकालय संदर्भों को अपनी परियोजना में शामिल कर रहे हैं।

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

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


1

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

यहाँ Adaptive Code Via C # से एक पैराग्राफ है :

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

- हॉल, गैरी मैकलीन। C # के माध्यम से अनुकूली कोड: डिजाइन पैटर्न और SOLID सिद्धांतों (डेवलपर संदर्भ) (पृष्ठ 309) के साथ चुस्त कोडिंग। पियर्सन शिक्षा।


0

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

क्लाइंट के पास स्पष्ट इंटरफ़ेस के माध्यम से एक सेवा (एक निर्भरता) के संदर्भ को स्वीकार करते हैं, आप

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

आप सही कह रहे हैं कि DI के अपने मुद्दे / नुकसान हैं, लेकिन उल्लिखित फायदे उन्हें दूर तक प्रभावित करते हैं ... IMO। आप सही कह रहे हैं, कि DI के साथ इंटरफ़ेस (निर्माता) में शुरू की गई निर्भरता है - लेकिन यह उम्मीद के मुताबिक बहुत निर्भरता है जिसकी आपको आवश्यकता है और जिसे आप दृश्यमान और जाँच योग्य बनाना चाहते हैं।


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

'स्थिर सूचना' / 'संकलन-समय जाँच' तर्क एक पुआल आदमी है। जैसा कि @davidoff ने बताया है, DI समान रूप से रनटाइम त्रुटियों के लिए अतिसंवेदनशील है। मैं यह भी जोड़ना चाहूंगा कि आधुनिक आईडीई सदस्यों के लिए टिप्पणी / सारांश जानकारी के टूलटिप विचार प्रदान करते हैं, और यहां तक ​​कि उन में भी, किसी के अभी भी प्रलेखन को देखने तक नहीं जा रहे हैं जब तक कि वे एपीआई को नहीं जानते हैं। दस्तावेज़ीकरण दस्तावेज़ीकरण है, चाहे एक आवश्यक निर्माता पैरामीटर या एक निर्भरता को कैसे कॉन्फ़िगर किया जाए, इस बारे में एक टिप्पणी।
ट्युस्पेटरे

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

0

हां, सर्विस लोकेटर एक एंटी-पैटर्न है, जो एनकैप्सुलेशन और सॉलिड का उल्लंघन करता है


1
मैं समझता हूं कि आपका क्या मतलब है लेकिन यह अधिक विस्तार से जोड़ने में मददगार होगा, जैसे कि यह SOLID का उल्लंघन क्यों करता है
reggaeguitar
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.