गाइस में @ImplementedBy एनोटेशन के पीछे क्या प्रेरणा है?


10

मैंने हाल ही @ImplementedByमें Google Guice में उपलब्ध एनोटेशन के बारे में पढ़ा । यह प्रोग्रामर को एक इंटरफेस के बीच एक बंधन को निर्दिष्ट करने और निर्भरता इंजेक्शन में भविष्य के उपयोग के लिए इसके कार्यान्वयन की अनुमति देता है। यह एक उचित समय के बंधन का एक उदाहरण है ।

मैं अपने सिंटैक्स का उपयोग करते हुए अपने मॉड्यूल में स्पष्ट बाइंडिंग को परिभाषित करने के लिए उपयोग किया जाता हूं:

bind(SomeInterface.class).to(SomeInterfaceImplementation.class);

प्रलेखन के अनुसार, यह @ImplementedByएनोटेशन के निम्नलिखित उपयोग के बराबर है :

@ImplementedBy(SomeInterfaceImplementation.class)
public interface SomeInterface {
    //method declarations
}

एकमात्र लाभ जो मैं यहां देख सकता हूं वह यह है कि कोड मामूली रूप से छोटा है। उसी समय, इस दृष्टिकोण में एक ही डॉक्स द्वारा इंगित की गई कमियां हैं:

@ImplementedByसावधानी से उपयोग करें ; यह इंटरफ़ेस से इसके कार्यान्वयन के लिए एक संकलन-समय पर निर्भरता जोड़ता है।

इस तरह की निर्भरता कई मामलों में समस्या नहीं हो सकती है, लेकिन मैं व्यक्तिगत रूप से इसे कोड गंध के रूप में देखता हूं।

क्या उपयोग के मामले @ImplementedByएनोटेशन को उपयोग करने लायक बनाते हैं ?

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

यदि एक प्रकार दोनों bind()कथन में है (पहले तर्क के रूप में) और @ImplementedByएनोटेशन है, तो bind()कथन का उपयोग किया जाता है। एनोटेशन एक डिफ़ॉल्ट कार्यान्वयन का सुझाव देता है जिसे बाध्यकारी के साथ ओवरराइड किया जा सकता है।

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

क्या यह एनोटेशन के अस्तित्व का एकमात्र कारण है? या मुझे कुछ याद आ रहा है? क्या मैं कोड में इसका उपयोग करके कुछ हासिल कर सकता हूं जो कि केवल कुछ व्यावसायिक तर्क का ख्याल रखने वाला एक आवेदन है और न कि पुस्तकालय / ढांचे को बढ़ाया जाना है?


2
संबंधित, संभवतः डुप्लिकेट प्रश्न (हालांकि आपका शीर्षक स्पष्ट है): क्या Guice's @ImplementedBy बुराई है?
जेफ बोमन

सख्त नकल नहीं, लेकिन इस पर कुछ दिलचस्प चर्चा हुई है: stackoverflow.com/questions/6197178/…
रिचर्ड वोडेन

जवाबों:


8

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

एक डिफ़ॉल्ट कार्यान्वयन परीक्षण के लिए महान है; आप जरूरी नहीं चाहते हैं कि हर बार जब आप किसी वर्ग का परीक्षण कर रहे हों, तो आपके पास एक मॉक इंजेक्शन को स्पष्ट रूप से परिभाषित करने की आवश्यकता हो, जिसमें बहुत सारी निर्भरताएं हों, या यदि आपके पास एक वर्ग है जो कई चीजें निर्भर हैं (इसलिए आपको हर बार एक नकली को परिभाषित करना होगा। )।

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

@ImplementedBy(NoOpDataService.class)
interface DataService {
    Map<String, MyPOJO> getData();
}

और फिर NoOpDataServiceहै:

class NoOpDataService implements DataService {
    @Override
    public Map<String, MyPOJO> getData() {
        return Collections.emptyMap();
    }
}

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

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


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