क्या मुझे डिपेंडेंसी इंजेक्शन या स्थिर कारखानों का उपयोग करना चाहिए?


81

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

  • इकाइयां एक दर्द का परीक्षण करती हैं और कार्यान्वयन की आसान अदला-बदली की अनुमति नहीं देती हैं। वे भी निर्भरता को स्पष्ट नहीं करते हैं (जैसे कि आप एक विधि की जांच कर रहे हैं, इस तथ्य से बेखबर है कि यह एक विधि को कहता है जो एक विधि को कॉल करता है जो एक डेटाबेस का उपयोग करता है)।
  • डिपेंडेसी इंजेक्शन बड़े पैमाने पर कंस्ट्रक्टर तर्क सूचियों को सूजता है और यह आपके कोड में कुछ पहलुओं को स्मीयर करता है। विशिष्ट स्थिति वह है जहां आधे से अधिक वर्गों के निर्माता इस तरह दिखते हैं(....., LoggingProvider l, DbSessionProvider db, ExceptionFactory d, UserSession sess, Descriptions d)

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

मैं इस तरह की समस्या से कैसे निपटूं ??


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

1
एक विधि के लिए बहुत सारे "इनपुट", वे पारित या इंजेक्ट किए जाते हैं, तरीकों के डिजाइन की अधिक समस्या है। आपके साथ जाने पर आप अपने तरीकों के आकार को थोड़ा कम कर सकते हैं (जो एक बार इंजेक्शन लगाने के बाद करना आसान है)
बिल के

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

जवाबों:


74

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

उदाहरण के लिए, आप एक नया प्रकार SessionEnvironmentसंलग्न कर सकते हैं DBSessionProvider, UserSessionऔर भरी हुई Descriptions। यह जानने के लिए कि कौन सा अमूर्त अर्थ सबसे अधिक है, हालांकि, किसी को आपके कार्यक्रम का विवरण जानना होगा।

इसी तरह का सवाल यहां पहले से ही एसओ से पूछा गया था ।


9
+1: मुझे लगता है कि कक्षाओं में कंस्ट्रक्टर के तर्क को एक बहुत अच्छा विचार है। यह आपको इन तर्क को अधिक अर्थ संरचनाओं में व्यवस्थित करने के लिए भी मजबूर करता है।
जियोर्जियो

5
लेकिन अगर परिणाम एक सार्थक संरचना नहीं है, तो आप एसआरपी का उल्लंघन करने वाली जटिलता को छिपा रहे हैं। इस मामले में एक क्लास रिफैक्टिंग किया जाना चाहिए।
danidacar

1
@ जियोर्जियो I एक सामान्य कथन से असहमत है कि "निर्माण तर्क को कक्षाओं में वर्गीकृत करना एक बहुत अच्छा विचार है।" यदि आप इसे "इस परिदृश्य में" के साथ अर्हता प्राप्त करते हैं तो यह अलग है।
tymtam

19

डिपेंडेसी इंजेक्शन बड़े पैमाने पर कंस्ट्रक्टर तर्क सूचियों को सूजता है और यह आपके कोड में कुछ पहलुओं को स्मीयर करता है।

उस से, ऐसा नहीं लगता है कि आप DI को उचित समझते हैं - विचार एक कारखाने के अंदर वस्तु तात्कालिकता पैटर्न को पलटना है।

आपकी विशिष्ट समस्या OOP की अधिक सामान्य समस्या प्रतीत होती है। ऑब्जेक्ट्स अपने रनटाइम के दौरान सामान्य, गैर-मानव-पठनीय अपवादों को क्यों नहीं फेंक सकते हैं, और फिर अंतिम प्रयास / पकड़ने से पहले कुछ होता है जो उस अपवाद को पकड़ता है, और उस बिंदु पर सत्र की जानकारी का उपयोग करके एक नया, प्रीटियर अपवाद छोड़ता है ?

एक अन्य दृष्टिकोण एक अपवाद कारखाना होगा, जो कि उनके निर्माणकर्ताओं के माध्यम से वस्तुओं को पारित किया जाता है। एक नया अपवाद फेंकने के बजाय, क्लास कारखाने की एक विधि पर फेंक सकता है (जैसे throw PrettyExceptionFactory.createException(data)

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


1
मैंने कहीं पढ़ा है कि जब आपकी पैरामीटर सूची बहुत लंबी हो जाती है तो ऐसा नहीं है क्योंकि आप निर्भरता इंजेक्शन का उपयोग कर रहे हैं, बल्कि इसलिए कि आपको अधिक निर्भरता इंजेक्शन की आवश्यकता है।
जियोर्जियो

इसका एक कारण हो सकता है - आम तौर पर, भाषा के आधार पर, आपके निर्माता के पास 6-8 से अधिक तर्क नहीं होने चाहिए, और उनमें से 3-4 से अधिक स्वयं वस्तुएं नहीं होनी चाहिए, जब तक कि विशिष्ट पैटर्न (पैटर्न की तरह Builder) न हो। इसे निर्देशित करता है। यदि आप अपने कंस्ट्रक्टर में पैरामीटर पास कर रहे हैं क्योंकि आपकी वस्तु अन्य ऑब्जेक्ट्स को इंस्टेंट करती है, तो यह आईओसी के लिए एक स्पष्ट मामला है।
जोनाथन रिच

12

आपने स्थैतिक फ़ैक्टरी पैटर्न के नुकसानों को पहले ही सूचीबद्ध कर लिया है, लेकिन मैं निर्भरता इंजेक्शन पैटर्न के नुकसानों से सहमत नहीं हूँ:

उस निर्भरता इंजेक्शन के लिए आपको प्रत्येक निर्भरता के लिए कोड लिखना आवश्यक है यह एक बग नहीं है, लेकिन एक विशेषता है: यह आपको यह सोचने के लिए मजबूर करता है कि क्या आपको वास्तव में इन निर्भरताओं की आवश्यकता है, जिससे ढीली युग्मन को बढ़ावा मिलेगा। आपके उदाहरण में:

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

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

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

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

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


इस। मैं एक अपवाद फेंकने के लिए DB को हिट करने की आवश्यकता नहीं देख सकता ।
कैलथ

1

निर्भरता इंजेक्शन का उपयोग करें। स्थैतिक कारखानों का उपयोग करना Service Locatorएंटीपैटर्न का एक रोजगार है । मार्टिन फाउलर के यहाँ सेमल का काम देखें - http://martinfowler.com/articles/injection.html

यदि आपका कंस्ट्रक्टर तर्क बहुत बड़ा हो गया है और आप सभी माध्यमों से DI कंटेनर का उपयोग नहीं कर रहे हैं, तो इंस्टेंटिएशन के लिए अपने स्वयं के कारखानों को लिखें, यह कॉन्फ़िगर करने योग्य होने की अनुमति देता है, या तो XML या इंटरफ़ेस के कार्यान्वयन को बाध्य करता है।


5
सेवा लोकेटर एक एंटीपैटर्न नहीं है - फाउलर खुद को आपके द्वारा पोस्ट किए गए URL में संदर्भित करता है। जबकि सेवा लोकेटर पैटर्न का दुरुपयोग किया जा सकता है (उसी तरह जिस तरह से सिंग्लेटन्स का दुरुपयोग किया जाता है - वैश्विक राज्य को दूर करने के लिए), यह एक बहुत ही उपयोगी पैटर्न है।
जोनाथन रिच

1
जानना दिलचस्प है। मैंने हमेशा सुना है कि इसे एक विरोधी पैटर्न के रूप में जाना जाता है।
सैम

4
यह केवल एक एंटीपैटर्न है यदि सेवा लोकेटर का उपयोग वैश्विक राज्य को संग्रहीत करने के लिए किया जाता है। सेवा लोकेटर तत्काल के बाद एक स्टेटलेस ऑब्जेक्ट होना चाहिए, और अधिमानतः अपरिवर्तनीय होना चाहिए।
जोनाथन रिच

XML सुरक्षित नहीं है। मैं इसे हर दूसरे दृष्टिकोण के असफल होने के बाद एक प्लान जेड
मानूंगा

1

मैं डिपेंडेंसी इंजेक्शन के साथ भी जाऊंगा। याद रखें कि DI न केवल कंस्ट्रक्टरों के माध्यम से किया जाता है, बल्कि संपत्ति बसने वालों के माध्यम से भी किया जाता है। उदाहरण के लिए, लकड़हारे को संपत्ति के रूप में इंजेक्ट किया जा सकता है।

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

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


4
मैं बसने वालों के माध्यम से DI से बचता हूं क्योंकि यह समय की एक खिड़की का परिचय देता है जिसके दौरान ऑब्जेक्ट पूरी तरह से प्रारंभिक स्थिति में नहीं है (निर्माणकर्ता और सेटर कॉल के बीच)। या दूसरे शब्दों में, यह एक विधि कॉल आदेश का परिचय देता है (Y से पहले X को कॉल करना चाहिए) जो कि संभव हो तो मैं इससे बचता हूं।
13

1
संपत्ति के माध्यम से DI वैकल्पिक निर्भरता के लिए आदर्श है। लॉगिंग एक अच्छा उदाहरण है। यदि आपको लॉगिंग की आवश्यकता है, तो लॉगर गुण सेट करें, यदि नहीं, तो इसे सेट न करें।
प्रेस्टन

1

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

मैं काफी सहमत नहीं हूँ। कम से कम सामान्य रूप से नहीं।

सरल कारखाना:

public IFoo GetIFoo()
{
    return new Foo();
}

सरल इंजेक्शन:

myDependencyInjector.Bind<IFoo>().To<Foo>();

दोनों स्निपेट एक ही उद्देश्य से काम करते हैं, वे एक लिंक सेट करते हैं IFooऔर Foo। बाकी सब सिर्फ वाक्यविन्यास है।

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

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


डिपेंडेसी इंजेक्शन बड़े पैमाने पर कंस्ट्रक्टर तर्क सूचियों को सूजता है और यह आपके कोड में कुछ पहलुओं को स्मीयर करता है।

यही कारण है कि कुछ लोग इस तरह के निर्माण में निर्भरता को स्पष्ट रूप से प्राप्त करना पसंद करते हैं:

public MyService()
{
    _myFoo = DependencyFramework.Get<IFoo>();
}

मैंने दलीलें सुनी हैं समर्थक (कोई निर्माता नहीं ब्लोट), मैंने दलीलें सुनाई हैं con (निर्माणकर्ता अधिक DI स्वचालन सक्षम करता है)।

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

तकनीकी स्तर पर, मैं किसी भी तरह से परवाह नहीं करता। टाइप करने के लिए या तो विकल्प के रूप में अधिक प्रयास लेता है। और जब से आप DI का उपयोग कर रहे हैं, आप आमतौर पर किसी भी तरह से एक निर्माता को कॉल नहीं करेंगे। लेकिन विजुअल स्टूडियो यूआई बग मुझे कंस्ट्रक्टर के तर्क को फूला नहीं समाता है।


साइड नोट के रूप में, निर्भरता इंजेक्शन और कारखाने परस्पर अनन्य नहीं हैं । मेरे पास ऐसे मामले हैं जहां एक निर्भरता डालने के बजाय, मैंने एक कारखाना डाला है जो निर्भरता उत्पन्न करता है (NInject सौभाग्य से आपको उपयोग करने की अनुमति देता है Func<IFoo>ताकि आपको वास्तविक कारखाना वर्ग बनाने की आवश्यकता न हो)।

इसके लिए उपयोग के मामले दुर्लभ हैं, लेकिन वे मौजूद हैं।


ओपी स्थिर कारखानों के बारे में पूछता है । stackoverflow.com/questions/929021/…
बसिलेव्स

@ बासीलेव्स "सवाल यह है कि, मैं इन घटकों को अन्य घटकों को प्रदान करने के बारे में कैसे जाऊँ।"
एंथनी रटलेज

1
@Basilevs सब कुछ मैंने कहा, साइड नोट के अलावा, स्थिर कारखानों पर भी लागू होता है। मुझे यकीन नहीं है कि आप विशेष रूप से इंगित करने की कोशिश कर रहे हैं। लिंक किसके संदर्भ में है?
फ्लेटर

क्या किसी कारखाने को इंजेक्ट करने का ऐसा उपयोग मामला हो सकता है, जहां एक ने एक सार HTTP अनुरोध वर्ग को तैयार किया है, और पांच अन्य बहुरूपी बाल वर्गों को रणनीतिक रूप से तैयार किया है, एक के लिए GET, POST, PUT, PATCH, और DELETE? आप यह नहीं जान सकते हैं कि MVC टाइप राउटर के साथ उक्त वर्ग पदानुक्रम को एकीकृत करने की कोशिश करते समय हर बार कौन सी HTTP पद्धति का उपयोग किया जाएगा (जो कि एक HTTP अनुरोध कक्षा पर भाग में भरोसा कर सकता है। PSR-7 HTTP संदेश इंटरफ़ेस बदसूरत है।
एंथनी रटलेज

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

0

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

<?php
namespace TFWD\Factories;

/**
 * A class responsible for instantiating
 * InboundHttpRequest objects (PHP 7.x)
 * 
 * @author Anthony E. Rutledge
 * @version 2.0
 */
class InboundHttpRequestFactory 
{
    private const GET = 'GET';
    private const POST = 'POST';
    private const PUT = 'PUT';
    private const PATCH = 'PATCH';
    private const DELETE = 'DELETE';

    private static $di;
    private static $method;

    // public function __construct(Injector $di, Validator $httpRequestValidator)
    // {
    //    $this->di = $di;
    //    $this->method = $httpRequestValidator->getMethod();
    // }

    public static function setInjector(Injector $di)
    {
        self::$di = $di;
    }    

    public static setMethod(string $method)
    {
        self::$method = $method;
    }

    public static function getRequest()
    {
        if (self::$method == self::GET) {
            return self::$di->get('InboundGetHttpRequest');
        } elseif ((self::$method == self::POST) && empty($_FILES)) {
            return self::$di->get('InboundPostHttpRequest');
        } elseif (self::$method == self::POST) {
            return self::$di->get('InboundFilePostHttpRequest');
        } elseif (self::$method == self::PUT) {
            return self::$di->get('InboundPutHttpRequest');
        } elseif (self::$method == self::PATCH) {
            return self::$di->get('InboundPatchHttpRequest');
        } elseif (self::$method == self::DELETE) {
            return self::$di->get('InboundDeleteHttpRequest');
        } else {
            throw new \RuntimeException("Unexpected HTTP request. Invalid request.");
        }
    }
}

MVC प्रकार सेटअप के लिए क्लाइंट कोड, एक केंद्रीकृत के भीतर index.php, निम्नलिखित (सत्यापन छोड़ा गया) की तरह लग सकता है।

InboundHttpRequestFactory::setInjector($di);
InboundHttpRequestFactory::setMethod($httpRequestValidator->getMethod());
$di->set('InboundHttpRequest', InboundHttpRequestFactory::getRequest());
$router = $di->get('Router');  // The Router class depends on InboundHttpRequest objects.
$router->dispatch(); 

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


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