2012-07-09 13 views
9

मैं जावा लाइब्रेरी बना रहा हूं, अंतिम उत्पाद के रूप में इसे वितरित करने के इरादे में .jar डेवलपर्स को वितरित करना चाहता हूं।जावा क्लास स्कोप और लाइब्रेरी

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

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

मेरा प्रश्न यह है कि मैं उद्देश्य-सी में क्या कर रहा था?

उदाहरण के लिए मेरे पास एक इवेंट क्लास है जो वास्तव में केवल आंतरिक रूप से उपयोग की जाती है और मैं नहीं चाहता कि उपयोगकर्ता इसके बारे में जान सके या इसके बारे में सोचें। मेरे पास एक और कक्षा TimedEvent है, जिसे उपयोगकर्ता प्रबंधन का एक उदाहरण प्राप्त कर सकता है।

मेरे उद्देश्य-सी में, मैंने पुस्तकालय सार्वजनिक दायरे से इवेंट क्लास को बाहर रखा, जिससे TimedEvent को अनुमति दी गई।

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

राय?

उत्तर

5

यह जावा के साथ संभव है लेकिन वहाँ कारण हैं (लगभग) कोई भी यह करता है ...

आप कार्यान्वयन और एक ही पैकेज में इंटरफ़ेस डाल, तो आप सब पहुँच संशोधक छोड़ सकते हैं (private , protected, public) कक्षाओं और विधियों से उन्हें "डिफ़ॉल्ट" या "पैकेज" दृश्यता देने के लिए: केवल उसी पैकेज में कक्षाओं को देखने/उनका उपयोग करने की अनुमति है।

दोष: आपको एपीआई और कार्यान्वयन मिश्रण करना होगा।

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

अंत में, आप इंटरफ़ेस के अंदर इंटरफ़ेस को कार्यान्वित कर सकते हैं। उदाहरण के लिए:

public interface IFoo { 
    String getName(); 

    private static class Foo implements IFoo { 
     public String getName(); 
    } 

    public static class FooFactory { 
     public static IFoo create() { return new Foo(); } 
    } 
} 

बदसूरत, है ना?

+2

अच्छा स्पर्श:

package com.my.main; public interface TimedEvent { void fire(); } package com.my.main.events; import com.my.main; public class EventFactory { public TimedEvent makeTimedEvent() { return new TimedEvent(); } } // TimedEventImpl has package visibility - it is not public. class TimedEventImpl implements TimedEvent { public void fire() { // Fire a timed event } } 

उपयोगकर्ताओं इस तरह TimedEvent का उपयोग होगा। क्या यह एक नई सुविधा है? –

+1

नहीं, चूंकि जावा आंतरिक कक्षाओं (1.2, मुझे लगता है) का समर्थन करता है, लेकिन यह बहुत सारे बॉयलर प्लेट कोड को जोड़ता है। –

+0

बहुत सारी पाठ्यपुस्तकों को यह गलत लगता है। "इंटरफ़ेस: स्थिरांक और विधि घोषणाएं" –

4

दुनिया में अपने वर्गों के संपर्क को नियंत्रित करने के लिए आम दृष्टिकोण इंटरफेस और कारखानों के पीछे कार्यान्वयन छुपा रहा है।

  • अपने TimedEvent के लिए एक इंटरफेस बनाएँ, और TimedEvent इंटरफ़ेस
  • के उदाहरण बनाने के लिए एक वर्ग एक उप पैकेज
  • में मुख्य पैकेज में इंटरफ़ेस, और कारखाने रखो कारखाने सार्वजनिक दृश्यता दें
  • उप पैकेज में इंटरफ़ेस को लागू है, यह दृश्यता पैकेज
  • वर्ग कारखाने में TimedEvent इंटरफेस को लागू करने का एक उदाहरण बना देने

यहाँ कैसे आप यह कर सकते का एक उदाहरण है: अंतरफलक के अंदर कार्यान्वयन पर

com.my.main.events.EventFactory f = new com.my.main.events.EventFactory(); 
com.my.main.TimedEvent evt = f.makeTimedEvent(); 
evt.fire(); 
संबंधित मुद्दे