IoC के लिए इंटरफेस के बजाय फंक का उपयोग करना


15

संदर्भ: मैं C # का उपयोग कर रहा हूं

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

मेरे लिए, यह एक बेहतर दृष्टिकोण की तरह लगता है क्योंकि मुझे यूनिट परीक्षण के दौरान कोई थकाऊ मॉकिंग करने की आवश्यकता नहीं है। इसके अलावा, अगर आस-पास के कार्यान्वयन में मूलभूत परिवर्तन हैं, तो मुझे केवल कारखाना वर्ग को बदलने की आवश्यकता होगी; वर्ग में तर्क वाले किसी भी बदलाव की आवश्यकता नहीं होगी।

हालाँकि, मैंने पहले कभी भी आईओसी को इस तरह से नहीं देखा है, जो मुझे लगता है कि कुछ संभावित नुकसान हैं जो मुझे याद आ रहे हैं। केवल एक ही मैं सोच सकता हूं कि सी # के पुराने संस्करण के साथ मामूली असंगति है, जो फंक को परिभाषित नहीं करता है, और यह मेरे मामले में कोई समस्या नहीं है।

अधिक विशिष्ट इंटरफेस के विपरीत जेनेरिक डेलीगेट्स / हायर ऑर्डर फ़ंक्शंस जैसे फंक का उपयोग करने में कोई समस्या है?


2
आप जो वर्णन कर रहे हैं वह उच्च-क्रम के कार्य हैं, कार्यात्मक प्रोग्रामिंग
रॉबर्ट हार्वे

2
इसके बजाय मैं एक प्रतिनिधि का उपयोग करूंगा Funcक्योंकि आप मापदंडों को नाम दे सकते हैं, जहां आप उनके इरादे बता सकते हैं।
स्टीफन हैंके

1
संबंधित: stackoverflow: ioc-factory-pros-&-contras-for-इंटरफ़ेस-बनाम-प्रतिनिधियों । @ TheWatWhisperer प्रश्न अधिक सामान्य है जबकि स्टैकओवरफ्लो प्रश्न विशेष मामले "फ़ैक्टरी" के लिए नीचे आता है
k3b

जवाबों:


11

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

मुझे लगता है कि बहुत से लोग उपयोग करने के लिए अधिक उपयोग किए जाते हैं interfaces , क्योंकि उस समय जब निर्भरता इंजेक्शन और IoC लोकप्रिय हो रहे थे, Funcजावा या सी ++ में कक्षा के बराबर कोई वास्तविक नहीं था (मुझे यकीन नहीं है Funcकि उस समय सी # में उपलब्ध था )। बहुत सारे ट्यूटोरियल, उदाहरण या पाठ्यपुस्तक अभी भी interfaceफॉर्म को पसंद करते हैं , भले ही उपयोग Funcकरना अधिक सुरुचिपूर्ण हो।

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

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


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

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

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

1
"... उस समय जब निर्भरता इंजेक्शन और आईओसी लोकप्रिय हो रहे थे, फंक क्लास के बराबर कोई वास्तविक नहीं था" डॉक्टर कि वास्तव में मैंने लगभग जवाब दिया लेकिन वास्तव में पर्याप्त आत्मविश्वास महसूस नहीं किया! उस एक पर मेरे संदेह को सत्यापित करने के लिए धन्यवाद।
ग्राहम

9

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

मुझे अक्सर यह भी पता चलता है कि एक एकल, सरल निर्भरता के साथ भी, कभी-कभी इसे एक से अधिक फ़ंक्शन करने की आवश्यकता होती है - एक इंटरफ़ेस आपको इन कार्यों को एक साथ समूह में करने की अनुमति देता है जो स्व-दस्तावेजीकरण है, बनाम ऐसे कई पैरामीटर हैं जो सभी पढ़ते हैं Func<string, string>, जैसे Func<string, int>

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


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

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

मेरे अनुभव में, यह केवल टूलींग का मामला है। ReSharpers निरीक्षण-> आने वाली कॉल फंक / लैम्ब्डा तक मार्ग को आगे बढ़ाने में एक अच्छा काम करती है।
क्रिश्चियन

3

अधिक विशिष्ट इंटरफेस के विपरीत जेनेरिक डेलीगेट्स / हायर ऑर्डर फ़ंक्शंस जैसे फंक का उपयोग करने में कोई समस्या है?

ज़रुरी नहीं। एक फंक इंटरफेस का अपना प्रकार है (अंग्रेजी अर्थ में, सी # अर्थ नहीं)। "यह पैरामीटर कुछ ऐसा है जो पूछने पर एक्स की आपूर्ति करता है।" फंक के पास केवल आवश्यकतानुसार सूचना की आपूर्ति करने का लाभ है। मैं इसे थोड़ा करता हूं और इसे मॉडरेशन में सुझाता हूं।

चढ़ाव के रूप में:

  • IoC कंटेनर अक्सर कैस्केड प्रकार में निर्भरता तार करने के लिए कुछ जादू करते हैं, और जब कुछ चीजें होती हैं Tऔर कुछ चीजें होती हैं , तो शायद अच्छा नहीं खेलेंगे।Func<T>
  • फ़नक्स में कुछ अप्रत्यक्षता है, इसलिए तर्क और डिबग के लिए थोड़ा कठिन हो सकता है।
  • फ़ंक्स देरी में देरी करता है, जिसका अर्थ है कि रनटाइम त्रुटियां परीक्षण के दौरान अजीब समय पर दिखाई दे सकती हैं या बिल्कुल नहीं। यह ऑपरेशन के मुद्दों के आदेश की संभावनाओं को भी बढ़ा सकता है और आपके उपयोग पर निर्भर करता है, प्रारंभिक क्रम में गतिरोध।
  • फ़ंक में आप जो भी पास करते हैं वह एक बंद होने की संभावना है, जिसमें थोड़ी सी भी अधिकता और जटिलताएं होती हैं।
  • किसी वस्तु को सीधे एक्सेस करने की तुलना में फंक कॉलिंग थोड़ा धीमा है। (इतना पर्याप्त नहीं है कि आप किसी भी गैर-तुच्छ कार्यक्रम में देखेंगे, लेकिन यह वहां है)

1
मैं कारखाने को पारंपरिक तरीके से बनाने के लिए IoC कंटेनर का उपयोग करता हूं, फिर कारखाना आपके पहले बिंदु में आपके द्वारा बताए गए मुद्दे के चारों ओर होते हुए, लैम्ब्डा में इंटरफेस के तरीकों को पैकेज करता है। अच्छे अंक।
दैटविस्परर

1

चलो एक सरल उदाहरण लेते हैं - शायद आप लॉगिंग के एक साधन को इंजेक्ट कर रहे हैं।

एक कक्षा में प्रवेश करना

class Worker: IWorker
{
    ILogger _logger;

    Worker(ILogger logger)
    {
        _logger = logger;
    }
    void SomeMethod()
    {
        _logger.Debug("This is a debug log statement.");
    }
}        

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

container.RegisterType<ILogger, ConcreteLogger>();
container.RegisterType<IWorker, Worker>();
....
var worker = container.Resolve<IWorker>();

जब डिबगिंग Worker , डेवलपर को यह निर्धारित करने के लिए कि क्या ठोस वर्ग का उपयोग किया जा रहा है, रचना रूट से परामर्श करने की आवश्यकता है।

यदि किसी डेवलपर को अधिक जटिल तर्क की आवश्यकता होती है, तो उसके पास काम करने के लिए संपूर्ण इंटरफ़ेस है:

    void SomeMethod()
    { 
       if (_logger.IsDebugEnabled) {
           _logger.Debug("This is a debug log statement.");
       }
    }

एक विधि का इंजेक्शन लगाना

class Worker
{
    Action<string> _methodThatLogs;

    Worker(Action<string> methodThatLogs)
    {
        _methodThatLogs = methodThatLogs;
    }
    void SomeMethod()
    {
        _methodThatLogs("This is a logging statement");
    }
}        

सबसे पहले, ध्यान दें कि कंस्ट्रक्टर पैरामीटर का अब एक लंबा नाम है methodThatLogs,। यह आवश्यक है क्योंकि आप यह नहीं बता सकते कि क्या Action<string>करना चाहिए। इंटरफ़ेस के साथ, यह पूरी तरह से स्पष्ट था, लेकिन यहां हमें पैरामीटर के नामकरण पर भरोसा करना होगा। यह एक निर्माण के दौरान लागू करने के लिए स्वाभाविक रूप से कम विश्वसनीय और कठिन लगता है।

अब, हम इस विधि को कैसे इंजेक्ट करते हैं? खैर, IoC कंटेनर आपके लिए ऐसा नहीं करेगा। इसलिए जब आप तुरंत करते हैं तो आप इसे स्पष्ट रूप से इंजेक्ट करते हैं Worker। यह कुछ समस्याओं को जन्म देता है:

  1. यह तत्काल काम करने के लिए अधिक है Worker
  2. डिबग करने का प्रयास करने वाले डेवलपर्स को Workerयह पता लगाना अधिक कठिन होगा कि ठोस उदाहरण को क्या कहा जाता है। वे सिर्फ रचना जड़ से परामर्श नहीं कर सकते हैं; उन्हें कोड के माध्यम से ट्रेस करना होगा।

कैसे के बारे में अगर हम और अधिक जटिल तर्क की आवश्यकता है? आपकी तकनीक केवल एक विधि को उजागर करती है। अब मुझे लगता है कि आप लैम्ब्डा में जटिल सामान सेंकना कर सकते हैं:

var worker = new Worker((s) => { if (log.IsDebugEnabled) log.Debug(s) } );

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

मतभेदों का सारांश:

  1. केवल एक विधि का इंजेक्शन लगाने से उद्देश्य का अनुमान लगाना कठिन हो जाता है, जबकि एक इंटरफ़ेस स्पष्ट रूप से उद्देश्य का संचार करता है।
  2. केवल एक विधि इंजेक्ट करने से इंजेक्शन प्राप्त करने वाले वर्ग को कम कार्यक्षमता उजागर होती है। यहां तक ​​कि अगर आपको आज इसकी आवश्यकता नहीं है, तो आपको कल इसकी आवश्यकता हो सकती है।
  3. आप केवल IoC कंटेनर का उपयोग करके स्वचालित रूप से केवल एक विधि इंजेक्ट नहीं कर सकते हैं।
  4. आप किसी विशेष उदाहरण में रचना की जड़ से नहीं बता सकते हैं कि कौन सा ठोस वर्ग काम में है।
  5. यह एक समस्या है जो लैम्बडा एक्सप्रेशन को स्वयं जांचने की इकाई है।

यदि आप उपरोक्त सभी के साथ ठीक हैं, तो बस विधि को इंजेक्ट करना ठीक है। नहीं तो मेरा सुझाव है कि आप परंपरा के साथ रहें और एक इंटरफ़ेस इंजेक्ट करें।


मुझे निर्दिष्ट करना चाहिए, मैं जो वर्ग बना रहा हूं वह एक प्रक्रिया तर्क वर्ग है। यह बाहरी वर्गों पर निर्भर करता है कि वह जिस डेटा को एक सूचित निर्णय लेने की आवश्यकता है उसे प्राप्त करने के लिए, इस तरह के एक लकड़हारे का उपयोग करने वाले साइड इफेक्ट का उपयोग नहीं किया जाता है। आपके उदाहरण के साथ एक मुद्दा यह है कि यह गरीब OO है, विशेष रूप से एक IoC कंटेनर का उपयोग करने के संदर्भ में। उपयोग करने के बजाय यदि कोई कथन, जो अतिरिक्त जटिलता को वर्ग में जोड़ता है, उसे बस एक अक्रिय लकड़हारा पारित किया जाना चाहिए। इसके अलावा, लैम्ब्डा में तर्क पेश करना वास्तव में कठिन परीक्षण करना होगा ... इसके उपयोग के उद्देश्य को पराजित करना, यही कारण है कि ऐसा नहीं किया गया है।
TheCatWhisperer

लैम्ब्डा एप्लिकेशन में एक इंटरफ़ेस विधि को इंगित करता है, और यूनिट परीक्षणों में मनमाने डेटा संरचनाओं का निर्माण करता है।
TheCatWhisperer

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

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

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

0

निम्नलिखित कोड पर विचार करें जो मैंने बहुत पहले लिखा था:

public interface IPhysicalPathMapper
{
    /// <summary>
    /// Gets the physical path represented by the relative URL.
    /// </summary>
    /// <param name="relativeURL"></param>
    /// <returns></returns>
    String GetPhysicalPath(String relativeURL);
}

public class EmailBuilder : IEmailBuilder
{
    public IPhysicalPathMapper PhysicalPathMapper { get; set; }
    public ITextFileLoader TextFileLoader { get; set; }
    public IEmailTemplateParser EmailTemplateParser { get; set; }
    public IEmaiBodyRenderer EmailBodyRenderer { get; set; }

    public String FromAddress { get; set; }

    public MailMessage BuildMailMessage(String templateRelativeURL, Object model, IEnumerable<String> toAddresses)
    {
        String templateText = this.TextFileLoader.LoadTextFromFile(this.PhysicalPathMapper.GetPhysicalPath(templateRelativeURL));

        EmailTemplate template = this.EmailTemplateParser.Parse(templateText);

        MailMessage email = new MailMessage()
        {
            From = new MailAddress(this.FromAddress),
            Subject = template.Subject,
            IsBodyHtml = true,
            Body = this.EmailBodyRenderer.RenderBodyToHtml(template.BodyTemplate, model)
        };

        foreach (MailAddress recipient in toAddresses.Select<String, MailAddress>(toAddress => new MailAddress(toAddress)))
        {
            email.To.Add(recipient);
        }

        return email;
    }
}

यह एक टेम्प्लेट फ़ाइल में एक सापेक्ष स्थान लेता है, इसे मेमोरी में लोड करता है, संदेश बॉडी को प्रस्तुत करता है, और ई-मेल ऑब्जेक्ट को असेंबल करता है।

आप देख सकते हैं IPhysicalPathMapperऔर सोच सकते हैं, "केवल एक ही कार्य है। यह एक हो सकता है Func।" लेकिन वास्तव में, यहाँ समस्या यह है कि IPhysicalPathMapperअस्तित्व में भी नहीं होना चाहिए। एक बेहतर समाधान सिर्फ मार्ग को छोटा करना है :

public class EmailBuilder : IEmailBuilder
{
    public ITextFileLoader TextFileLoader { get; set; }
    public IEmailTemplateParser EmailTemplateParser { get; set; }
    public IEmaiBodyRenderer EmailBodyRenderer { get; set; }

    public String FromAddress { get; set; }

    public MailMessage BuildMailMessage(String templatePath, Object model, IEnumerable<String> toAddresses)
    {
        String templateText = this.TextFileLoader.LoadTextFromFile(templatePath);

        EmailTemplate template = this.EmailTemplateParser.Parse(templateText);

        MailMessage email = new MailMessage()
        {
            From = new MailAddress(this.FromAddress),
            Subject = template.Subject,
            IsBodyHtml = true,
            Body = this.EmailBodyRenderer.RenderBodyToHtml(template.BodyTemplate, model)
        };

        foreach (MailAddress recipient in toAddresses.Select<String, MailAddress>(toAddress => new MailAddress(toAddress)))
        {
            email.To.Add(recipient);
        }

        return email;
    }
}

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

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

इंटरफेस को संयम से इस्तेमाल किया जाना चाहिए, और नियंत्रण और निर्भरता इंजेक्शन के व्युत्क्रम को भी संयम से इस्तेमाल किया जाना चाहिए। यदि आपके पास इनकी बड़ी मात्रा है, तो आपके कोड को समझने में काफी मुश्किल हो जाती है।

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