2013-03-04 8 views
17
में एकल विधि इंटरफेस का उपयोग करने के

मैं Spring जो एकल तरीकों BeanNameAware की तरह उन में साथ इंटरफेस का एक बहुत का उपयोग करें, आदिजब जावा

जैसे कई पुस्तकालयों में देखा है और implementer वर्ग के साथ कई इंटरफेस को लागू करेगा एकल तरीकों

एकल विधि इंटरफेस रखने के लिए किन स्थितियों में यह समझ में आता है? उदाहरण के लिए ResultSet उदाहरण के लिए एक एकल इंटरफेस भारी बनाने से बचने के लिए किया जाता है? या क्या कोई डिज़ाइन मानक है जो इन प्रकार के इंटरफेस के उपयोग की वकालत करता है?

उत्तर

13

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

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

उदाहरण:

interface SingleMethod{ //The single method interface 
    void foo(int i); 
} 

class X implements SingleMethod { //A class implementing it (and probably other ones) 
    void foo(int i){...} 
} 

class Y { //An unrelated class that has methods with matching signature 
    void bar(int i){...} 
    static void bar2(int i){...} 
} 

class Framework{ // A framework that uses the interface 
    //Takes a single method object and does something with it 
    //(probably invoking the method) 
    void consume(SingleMethod m){...} 
} 

class Client{ //Client code that uses the framework 
    Framework f = ...; 
    X x = new X(); 
    Y y = new Y(); 
    f.consume(x); //Fine, also in Java 7 

    //Java 8 
    //ALL these calls are only possible since SingleMethod has only ONE method! 
    f.consume(y::bar); //Simply hand in a method. Object y is bound implicitly 
    f.consume(Y::bar2); //Static methods are fine, too 
    f.consume(i -> { System.out.println(i); }) //lambda expression. Super concise. 

    //This is the only way if the interface has MORE THAN ONE method: 
    //Calling Y.bar2 Without that closure stuff (super verbose) 
    f.consume(new SingleMethod(){ 
     @Override void foo(int i){ Y.bar2(i); } 
    }); 
} 
+5

'f.consume (i -> {System.out.println (i);}) 'को संक्षेप में सारांशित किया जा सकता है:' f.consume (System.out :: println);' –

4

केवल एक (या कुछ) विधियों के साथ इंटरफेस अत्यधिक उपयोगी Strategy pattern की कुंजी है, जो "कुछ डिज़ाइन मानक है जो इन प्रकार के इंटरफेस के उपयोग की वकालत करता है"।

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

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

+0

सत्य हैं। क्या इसके लिए कोई और फायदे हैं? –

+2

मैं कहूंगा कि रणनीति पैटर्न स्वयं ही एक लाभ का पर्याप्त है। लेकिन मैं अपना जवाब विस्तारित करने का प्रयास कर सकता हूं। –

+2

अगले जावा में लैम्ब्डा अभिव्यक्तियों के लिए फायदे तैयार किए जा रहे हैं। –

0

एकल परिदृश्य इंटरफेस रखने के लिए किन स्थितियों में यह समझ में आता है?

ऐसे परिदृश्यों में जब आपको केवल एक विधि के साथ इंटरफेस की आवश्यकता होती है।

इंटरफेस का उपयोग कई वर्गों के सामान्य व्यवहार को समाहित करने के लिए किया जाता है। इसलिए यदि आपके कोड में कई जगहें हैं जहां आपको केवल क्लास विधियों के सीमित सेट को कॉल करने की आवश्यकता है, तो यह एक इंटरफ़ेस पेश करने का समय है। विधियों की संख्या इस बात पर निर्भर करती है कि आपको कॉल करने की क्या ज़रूरत है। कभी-कभी आपको one विधि की आवश्यकता होती है, कभी-कभी two या more, कभी-कभी आप don't need methods at all। क्या मायने रखता है कि आप व्यवहार को कार्यान्वयन से अलग कर सकते हैं।

0

Favor Composition over InheritanceHead First Design Pattern की ट्यूटोरियल किताब एक वर्ग को गतिशील कार्यक्षमता जोड़ने के लिए इस दृष्टिकोण की सिफारिश की। आइए नीचे केस लें:

public interface Quackable { 
    public void quack(); 
} 

public class Quacks implements Quackable { 
    public void quack(){ 
     //quack behavior 
    } 
} 

public class DontQuack implements Quackable { 
    public void quack(){ 
     //dont quack 
    } 
} 

public class QuackableDuck{ 
    Quackable quack; //add behavior dynamicall 

} 

तो QuackableDuck क्लास गतिशील रूप से सुविधा जोड़ सकता है।

quack = new Quacks(); 
    //or 
    quack = new DontQuack(); 

इसी तरह आप कक्षा में गतिशील रूप से कई व्यवहार जोड़ सकते हैं।

3

यह निश्चित रूप से सिंगल-विधि इंटरफेस के संदिग्ध होने के लिए अच्छा है, इसलिए प्रश्न के लिए +1।

लेकिन आप जानते हैं, आप संबंधित तरीकों के समूह का समर्थन करने के लिए एक इंटरफ़ेस बनाते हैं। यदि आपके पास वास्तव में ऐसी कोई विधि है जो किसी अन्य विधि से स्पष्ट रूप से संबंधित नहीं है, तो एक एकल विधि इंटरफ़ेस उचित है।

कहाँ संदेह में आता है, जहां आप एक कदम पीछे जाएं और कहते हैं, "अब इस विधि वास्तव में कुछ और से संबंधित नहीं है?" यदि आप खुश हैं कि यह नहीं है, तो यह "सही" समय है।

0

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

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