6

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

मैंने समान पदों को देखा है और पूरी तरह से समझ में नहीं आये हैं।

उत्तर

18

निर्भरता इंजेक्शन कक्षा को यह कहने के पैटर्न को संदर्भित करता है कि क्लास को इसकी सभी निर्भरताओं को कहां से ढूंढना है, इसकी आवश्यकता के बजाय। कुछ इस तरह के

public class UserFetcher { 
    private final DbConnection conn = 
     new DbConnection("10.167.1.25", "username", "password"); 

    public List<User> getUsers() { 
     return conn.fetch(...); 
    } 
} 

:

तो, उदाहरण के लिए, आप इस से जाना

public class UserFetcher { 
    private final DbConnection conn; 

    public UserFetcher(DbConnection conn) { 
     this.conn = conn; 
    } 

    public List<User> getUsers() { 
     return conn.fetch(...); 
    } 
} 

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

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

एक ऐसे मामले के बारे में सोचें जहां UserFetcherAccountManager की निर्भरता है, जो AdminConsole की निर्भरता है। तब AdminConsole जरूरतों AccountManager को DbConnection उदाहरण पारित करने के लिए, और AccountManager जरूरतों UserFetcher करने के लिए इसे पारित करने के लिए ... भले ही न AdminConsole है और न ही AccountManager सीधे DbConnection उपयोग करने के लिए की जरूरत है!

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

तो हमारे पिछले उदाहरण Guice के साथ इस प्रकार दिखाई देंगे, अगर हम निर्माता इंजेक्शन का इस्तेमाल किया:

public class UserFetcher { 
    private final DbConnection conn; 

    @Inject //or @Autowired for Spring 
    public UserFetcher(DbConnection conn) { 
     this.conn = conn; 
    } 

    public List<User> getUsers() { 
     return conn.fetch(...); 
    } 
} 

और हम आईओसी कंटेनर कॉन्फ़िगर करने के लिए की है। Guice में यह Module के कार्यान्वयन के माध्यम से किया जाता है; वसंत में आप एप्लिकेशन संदर्भ को अक्सर एक्सएमएल के माध्यम से कॉन्फ़िगर करते हैं।

public class MyGuiceModule extends AbstractModule {  
    @Override 
    public void configure() { 
     bind(DbConnection.class).toInstance(
      new DbConnection("localhost", "username", "password")); 
    } 
} 

अब जब UserFetcher Guice या वसंत द्वारा निर्माण किया है, DbConnection स्वचालित रूप से प्रदान की जाती है।

गुइस के पास निर्भरता इंजेक्शन के पीछे प्रेरणा पर a really good Wiki article है, और आगे एक आईओसी कंटेनर का उपयोग कर। यह सभी तरह से पढ़ने लायक है।

रणनीति पैटर्न सिर्फ निर्भरता इंजेक्शन, जहाँ आप तर्क के बजाय एक वस्तु (भले ही जावा में, तर्क एक वस्तु में समाहित किया जाएगा) इंजेक्षन की एक विशेष मामला है। यह स्वतंत्र व्यापार तर्क decoupling का एक तरीका है।

उदाहरण के लिए, अगर आप इस तरह कोड हो सकता है:

public Currency computeTotal(List<Product> products) { 
    Currency beforeTax = computeBeforeTax(products); 
    Currency afterTax = beforeTax.times(1.10); 
} 

लेकिन क्या होगा अगर आप एक अलग बिक्री कर योजना के साथ, एक नया अधिकार क्षेत्र के लिए इस कोड का विस्तार करना चाहते थे? आप कर की गणना करने, इस तरह तर्क इंजेक्षन सकता है:

public interface TaxScheme { 
    public Currency applyTax(Currency beforeTax); 
} 

public class TenPercentTax implements TaxScheme { 
    public Currency applyTax(Currency beforeTax) { 
     return beforeTax.times(1.10); 
    } 
} 

public Currency computeTotal(List<Product> products, TaxScheme taxScheme) { 
    Currency beforeTax = computeBeforeTax(products); 
    Currency afterTax = taxScheme.applyTax(beforeTax); 
    return afterTax; 
} 
2

नियंत्रण से उलट मतलब है कि एक क्रम ढांचे तारों सब एक साथ घटकों (उदाहरण के वसंत के लिए)। निर्भरता इंजेक्शन आईओसी का एक रूप है (मुझे नहीं पता कि आईओसी का दूसरा रूप मौजूद है) (देखें: http://en.wikipedia.org/wiki/Inversion_of_control)।

रणनीति पैटर्न एक डिजाइन पैटर्न (गोफ द्वारा परिभाषित) है जहां एल्गोरिदम को दूसरे द्वारा प्रतिस्थापित किया जा सकता है (देखें: http://en.wikipedia.org/wiki/Strategy_pattern)। यह एक ही इंटरफ़ेस के कई कार्यान्वयन प्रदान करके संग्रहीत किया जाता है। स्प्रिंग जैसे आईओसी का उपयोग करते समय, यदि आपके पास इंटरफ़ेस के कई कार्यान्वयन हैं, और यदि आप कॉन्फ़िगरेशन द्वारा किसी अन्य कार्यान्वयन से स्विच कर सकते हैं, तो आप रणनीति पैटर्न का उपयोग कर रहे हैं।

0

मैं भी इस मुद्दे पर केंद्रित है, जो इस मुद्दे पर केंद्रित है: Introduction to Spring Framework
पहले कुछ पैराग्राफ करना चाहिए।

और यह भी लिंक करता है: Inversion of Control Containers and the Dependency Injection pattern
जो इन महत्वपूर्ण कोर अवधारणाओं का प्रेरक दृश्य भी प्रदान करता है।