2016-10-06 4 views
30

मैंने कुछ पोस्टों में Spring MVC और Portlets के बारे में पढ़ा है कि फ़ील्ड इंजेक्शन की अनुशंसा नहीं की जाती है। क्योंकि मैं एक प्राप्त करने की कोशिश कर रहा हूं इसलिए मैंने खुद से पूछा कि क्या मैं फ़ील्ड इंजेक्शन का उपयोग कर रहा हूं और मैं इसका उत्तर नहीं दे सकता। के रूप में मैं इसे क्षेत्र इंजेक्शन को समझने है अगर आप @Autowired इस तरह के साथ एक विशेषता में एक Bean इंजेक्षन:फील्ड इंजेक्शन वास्तव में क्या है और इससे कैसे बचें?

CartController.java:

... 
@Autowired 
private Cart cart; 
... 

BookshopConfiguartion.java:

@Configuration 
public class BookShopConfiguration { 

@Bean 
public Cart cart(){ 
    return new Cart(); 
} 
//more configuration 

मेरा Cart.java का उपयोग स्टोर करने और जानकारी प्रदान करने के लिए किया जाता है गाड़ी में किताबें।

अपना शोध के दौरान मैं के बारे में निर्माता इंजेक्शन पढ़ें:

MyComponent.java:

... 
public class MyComponent{ 
private Cart cart; 

@Autowired 
public MyComponent(Cart cart){ 
    this.cart = cart; 
} 
... 

फायदे और इंजेक्शन के इन प्रकार के दोनों का नुकसान क्या हैं?


संपादित करें 1: के रूप में इस सवाल का this question की डुप्लीकेट मैं यह जाँच के रूप में चिह्नित किया गया है। क्योंकि कोई कोड उदाहरण नहीं हैं, न तो प्रश्न में और न ही जवाब में यह मुझे स्पष्ट नहीं है कि अगर मैं अपने अनुमान के साथ सही हूं कि इंजेक्शन प्रकार का उपयोग मैं कर रहा हूं।

उत्तर

70

इंजेक्शन प्रकार

तीन विकल्प कैसे निर्भरता एक सेम में इंजेक्ट किया जा सकता है: 1. निर्माता 2. setters या अन्य तरीकों 3. प्रतिबिंब के माध्यम से के माध्यम से के माध्यम से सीधे खेतों में

आप विकल्प 3 का उपयोग कर रहे हैं - वह तब होता है जब आप अपने क्षेत्र पर सीधे @Autowired का उपयोग करते हैं।


इंजेक्शन दिशा निर्देशों

एक सामान्य दिशानिर्देश, as recommended also by Spring (देखें निर्माता आधारित या सेटर आधारित डि अनुभाग) पीछा कर रहा है:

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

फील्ड इंजेक्शन कमियां

कारण क्षेत्र इंजेक्शन पर सिकोड़ी है निम्नलिखित हैं:

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

निष्कर्ष

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


इसके अलावा

पढ़ना मैं क्यों क्षेत्र इंजेक्शन आमतौर पर की सिफारिश नहीं कर रहा है के बारे में एक ब्लॉग लेख लिखा था - आप इसे यहां से जांच कर सकते हैं - Field Dependency Injection Considered Harmful

+4

यह सामान्य बात नहीं है और दुनिया को बताने में अच्छा नहीं है "फील्ड इंजेक्शन से बचा जाना चाहिए"। पेशेवरों और contras दिखाएं और दूसरों को खुद को तय करने दें;) कई लोगों के पास अन्य अनुभव और चीजों को देखने का अपना तरीका है। – dit

+4

यह मामला यहां हो सकता है, लेकिन ऐसे कई मामले हैं जहां समुदाय कुछ हतोत्साहित करने के लिए आम सहमति के लिए आया है। उदाहरण के लिए, हंगेरियन नोटेशन लें। – Jannik

+0

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

11

स्वाद का मामला। यह आपका निर्णय है।

लेकिन मैं समझा सकता हूं, मैं कभी भी कन्स्ट्रक्टर इंजेक्शन का उपयोग क्यों नहीं करता।

  1. मैं अपने सभी @Service, @Repository और @Controller सेम के लिए एक निर्माता लागू करने के लिए नहीं करना चाहती। मेरा मतलब है, लगभग 40-50 सेम या अधिक हैं। हर बार जब मैं एक नया क्षेत्र जोड़ता हूं तो मुझे कन्स्ट्रक्टर का विस्तार करना होगा। नहीं। मुझे यह नहीं चाहिए और मुझे नहीं करना है।

  2. क्या होगा यदि आपकी बीन (सेवा या नियंत्रक) को इंजेक्शन देने के लिए कई अन्य बीन्स की आवश्यकता होती है? 8 पैरामीटर के साथ एक कन्स्ट्रक्टर बहुत बदसूरत है।

  3. यदि मैं सीडीआई का उपयोग कर रहा हूं, तो निर्माता मुझे चिंता नहीं करता है।


संपादित: Vojtech रुज़िका ने कहा:

वर्ग भी कई निर्भरता है और शायद ही जिम्मेदारी सिद्धांत उल्लंघन कर रहा है और

हाँ पुनर्संशोधित किया जाना चाहिए। सिद्धांत और वास्तविकता। यहां एक उदाहरण है: DashboardController एकल पथ *:8080/dashboard पर मैप किया गया।

मेरा DashboardController अन्य सेवाओं से उन्हें डैशबोर्ड/सिस्टम अवलोकन पृष्ठ में प्रदर्शित करने के लिए कई सारी जानकारी एकत्र करता है। मुझे इस सिंगल कंट्रोलर की ज़रूरत है। तो मुझे केवल यह एक रास्ता सुरक्षित करना है (मूल लेख या उपयोगकर्ता भूमिका फ़िल्टर)।

+10

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

+1

@VojtechRuzicka यह निश्चित रूप से अच्छा नहीं है लेकिन कभी-कभी आप इससे बच नहीं सकते हैं। – dit

+2

मैं 3 के अंगूठे का नियम कहूंगा, 40-50 अकेले रहने दो, किसी भी वर्ग के लिए निर्भरता एक संकेत होना चाहिए जिसे आपको रिफैक्टर करने की आवश्यकता है। 40 निर्भरताओं वाली कक्षा कोई भी तरीका नहीं है जो एकल जिम्मेदारी प्रिंसिपल या ओपन/क्लोज प्रिंसिपल पर चिपक रही है। –

17

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

निर्माता इंजेक्शन

सकारात्मक:

  • बेहतर testability। यूनिट परीक्षणों में आपको किसी भी मॉकिंग लाइब्रेरी या स्प्रिंग संदर्भ की आवश्यकता नहीं है। आप एक ऑब्जेक्ट बना सकते हैं जिसे आप नया कीवर्ड से परीक्षण करना चाहते हैं। ऐसे परीक्षण हमेशा तेज होते हैं क्योंकि वे प्रतिबिंब तंत्र पर भरोसा नहीं करते हैं। (This question को 30 मिनट बाद पूछा गया था। अगर लेखक ने कन्स्ट्रक्टर इंजेक्शन का इस्तेमाल किया होता तो यह दिखाई नहीं देता था)।
  • अपरिवर्तनीयता। एक बार निर्भरता सेट हो जाने पर उन्हें बदला नहीं जा सकता है।
  • सुरक्षित कोड। एक कन्स्ट्रक्टर के निष्पादन के बाद आपकी ऑब्जेक्ट उपयोग करने के लिए तैयार है क्योंकि आप पैरामीटर के रूप में पारित की गई किसी भी चीज़ को मान्य कर सकते हैं। ऑब्जेक्ट या तो तैयार हो सकता है या नहीं, बीच में कोई राज्य नहीं है। जब आप ऑब्जेक्ट नाजुक होते हैं तो फ़ील्ड इंजेक्शन के साथ आप मध्यवर्ती चरण का परिचय देते हैं।
  • अनिवार्य निर्भरताओं की क्लीनर अभिव्यक्ति। फील्ड इंजेक्शन इस मामले में संदिग्ध है।
  • डेवलपर्स को डिजाइन के बारे में सोचता है। बिट ने 8 पैरामीटर के साथ एक कन्स्ट्रक्टर के बारे में लिखा, जो वास्तव में एक खराब डिजाइन और the God object anti-pattern का संकेत है। इससे कोई फर्क नहीं पड़ता कि किसी वर्ग के अपने कन्स्ट्रक्टर या फ़ील्ड में 8 निर्भरताएं हैं, यह हमेशा गलत है। लोग खेतों के मुकाबले एक कन्स्ट्रक्टर को अधिक निर्भरता जोड़ने के लिए अधिक अनिच्छुक हैं। यह आपके दिमाग के संकेत के रूप में काम करता है कि आपको थोड़ी देर के लिए रुकना चाहिए और अपनी कोड संरचना के बारे में सोचना चाहिए।

विपक्ष:

  • अधिक कोड (लेकिन आधुनिक IDEs दर्द को कम)।

मूल रूप से, फ़ील्ड इंजेक्शन विपरीत है।

संबंधित मुद्दे