क्या जावा पैकेज स्तर गुंजाइश उपयोगी है?


11

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

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

उदाहरण के लिए मेरे पास एक मिशन मॉडल हो सकता है और मुझे कुछ तरीकों का उपयोग करने के लिए मेरे मिशनसर्विस की तरह केवल अन्य मिशन उपकरण चाहिए। हालाँकि, मैं अपने पैकेज के रूप में Missions.models और Missions.services के साथ अंत करता हूं, इसलिए मिशनमॉडल और मिशन सेवा एक ही पैकेज गुंजाइश नहीं हैं। ऐसा कभी नहीं लगता कि कोई ऐसी स्थिति है जहाँ पैकेज उचित रूप से उन चीज़ों को सम्‍मिलित करते हैं जिन्हें मैं बिना अनुमति के बढ़ाना चाहता हूँ, जिसमें कई चीज़ें शामिल हैं जिन्हें मैं उन अनुमतियों के लिए नहीं चाहता; और शायद ही कभी मुझे लगता है कि पैकेज स्कूपिंग का फायदा एक विधि को एक ही पैकेज में सब कुछ रखने के लिए मेरी परियोजना वास्तुकला को संशोधित करने के लिए उचित है। अक्सर या तो पहलू या किसी प्रकार का नियंत्रण उलटा हो जाता है जो भी समस्या के लिए बेहतर तरीका होता है, जिसके लिए मैं पैकेज को संक्षेप में समझता हूं।

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

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


सोचा प्रयोग: यदि आपके पास पैकेज नहीं थे तो जावा प्रोग्राम क्या दिखेंगे? ऐसा हो सकता है कि आपने किसी बड़े जावा प्रोग्राम को देखा या काम नहीं किया हो ।
रॉबर्ट हार्वे

के लिए कोड देखें java.util.Stringऔर java.util.Integer


2
डुप्लिकेट प्रश्न पर शीर्ष-वोट किया गया उत्तर पैकेज-निजी के लिए सबसे महत्वपूर्ण उपयोग को शामिल करता है, इसका स्पष्ट रूप से उत्तर है कि यह उपयोगी क्यों है।

2
मैं नकल से बिल्कुल आश्वस्त नहीं हूं। यह सवाल पूछ रहा है "पैकेज की गुंजाइश क्या है?" जबकि दूसरा पूछ रहा है (अन्य बातों के अलावा) "पैकेज का दायरा तयशुदा है, निजी गुंजाइश क्या है?" प्लस ड्यूप पर स्वीकृत उत्तर और यहां स्वीकृत उत्तर पूरी तरह से अलग बिंदु बना रहा है।
Ixrec

जवाबों:


2

पूरे java.util.*पैकेज में ऐसे उदाहरण हैं जहां कोड को पैकेज स्तर की सुरक्षा के साथ लिखा गया है। उदाहरण के लिए, इस बिट java.util.String- जावा 6 में एक निर्माता :

// Package private constructor which shares value array for speed.
String(int offset, int count, char value[]) {
    this.value = value;
    this.offset = offset;
    this.count = count;
}

या इस getChars विधि :

/** Copy characters from this string into dst starting at dstBegin. 
    This method doesn't perform any range checking. */
void getChars(char dst[], int dstBegin) {
    System.arraycopy(value, offset, dst, dstBegin, count);
}

इसका कारण यह है कि कोड के डिजाइनरों (और java.util.*एक बड़ी लाइब्रेरी के रूप में सोचा जा सकता है) विभिन्न सुरक्षा के नुकसान की लागत पर तेज प्रदर्शन करने की क्षमता चाहते थे (सरणियों पर सीमा की जांच, अन्य क्षेत्रों में सीधे पहुंच) इसका मतलब यह है कि इंटरफ़ेस के बजाय कार्यान्वयन, क्लास के कुछ हिस्सों के लिए 'असुरक्षित' पहुंच जो अन्यथा अन्य तरीकों के माध्यम से अपरिवर्तनीय माना जाता है)।

इन विधियों और क्षेत्रों को केवल java.utilपैकेज में अन्य वर्गों द्वारा एक्सेस करने के लिए प्रतिबंधित करके , यह उनके बीच घनिष्ठ युग्मन के लिए बनाता है, लेकिन दुनिया के लिए इन कार्यान्वयन विवरणों को उजागर करने से भी बचता है।

यदि आप किसी एप्लिकेशन पर काम कर रहे हैं और आपको अन्य उपयोगकर्ताओं के बारे में चिंता करने की आवश्यकता नहीं है, तो पैकेज स्तर की सुरक्षा कुछ ऐसी चीज नहीं है जिसके बारे में आपको चिंता करने की आवश्यकता है। डिजाइन शुद्धता के विभिन्न पहलुओं के अलावा, आप सब कुछ बना सकते हैं publicऔर इसके साथ ठीक हो सकते हैं ।

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


1
मैंने java.util के माध्यम से देखा और मुझे वह दिखता है। हालाँकि, मैंने यह भी देखा कि यह एक बड़ी लाइब्रेरी है। अब दिनों में ऐसा लगता है कि उप-पैकेजों का उपयोग किए बिना बड़े पैमाने पर पुस्तकालय लिखे गए हैं; और यह उन उप-पैकेज डिवीजनों को सीमित करता है। मैं यह नहीं कह रहा हूँ java.util गलत है, लेकिन ऐसा लगता है जैसे वे एक बड़े पैकेज केवल क्योंकि वे किया था के साथ भाग मिल सकता है बेहद अच्छा programers वे एक पैकेज के भीतर नहीं बल्कि सीमित कैप्सूलीकरण के साथ सब कुछ सही करने के लिए पर भरोसा कर सकता है; मुझे लगता है कि औसत डेवलपर्स को बुरा करने की बहुत संभावना है कि मेरे जैसे ही पैकेज पर काम कर सकता है।
dsollen

1
@dsollen यदि आप स्प्रिंग में खुदाई करते हैं, और हाइबरनेट या इसी तरह के बड़े पुस्तकालयों में आपको समान चीजें मिलेंगी। ऐसे समय होते हैं जब आपको निकट युग्मन की आवश्यकता होती है। एक को सबमिशन की समीक्षा करने और सब कुछ सही होने का सुनिश्चित करने का अवसर होना चाहिए । यदि आपको नज़दीकी युग्मन की आवश्यकता नहीं है, या अन्य कोडर्स पर बिल्कुल भी भरोसा नहीं करते हैं, तो सार्वजनिक फ़ील्ड, या पैकेज या संरक्षित फ़ील्ड या विधियाँ हमेशा उपयुक्त होती हैं। हालाँकि, इसका मतलब यह नहीं है कि यह उपयोगी नहीं है।

संक्षेप में, मुझे अपनी रोज़मर्रा की जरूरतों के लिए अधिक प्रतिबंधित पैकेज बनाने और अनुकूलन के स्तर (जो कि 95% परियोजनाओं में सिर्फ एक बेकार है) के बारे में चिंता नहीं करने के लिए लुभाया जाएगा। इस प्रकार मेरा अनुवर्ती सवाल यह है कि पैकेज स्तर की गुंजाइश एक बहुत विशिष्ट अनुकूलन क्षमता है जिसका उपयोग केवल कुछ बड़े पैमाने पर उपयोग किए जाने वाले बड़े पैमाने पर एपीआई में किया जाता है? IE केवल महानता की आवश्यकता होगी, या चाहते हैं, उस हद तक सुरक्षा को आराम करने के लिए? क्या ऐसे कारण हैं कि छोटे उपयोगकर्ता आधार के साथ 'मानक' एपीआई पर काम करने वाले अच्छे प्रोग्रामर इसके लिए उपयोग करेंगे?
dsollen

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

2
@dsollen यह प्रदर्शन के बारे में नहीं है (हालांकि यह कार्यान्वयन को उजागर करने का एक कारण है), लेकिन इनकैप्सुलेशन। आप इसे कोड को दोहराने से बचने के लिए करते हैं Integer.toString()और String.valueOf(int)इसे दुनिया को उजागर किए बिना कोड साझा कर सकते हैं। java.utilकक्षाएं संगीत कार्यक्रम में काम करने के लिए नहीं बल्कि अलग अलग वर्गों है कि पूरी तरह से स्वयं के इधार द्वीप हैं होने से कार्यक्षमता का एक बड़ा पूरे प्रदान करने के लिए कर रहे हैं - वे के माध्यम से पैकेज स्तर scoping एक पैकेज और शेयर कार्यान्वयन कार्यक्षमता में एक साथ कर रहे हैं।

5

कुछ समय के लिए मैं निजी या संरक्षित तरीकों की दृश्यता को बढ़ाता हूं ताकि कुछ कार्यान्वयन विवरण तक पहुंचने के लिए जून-टेस्ट की अनुमति दी जा सके जिसे बाहर से एक्सेस नहीं किया जाना चाहिए।

चूँकि जूनट-टेस्ट में आइटम-अंडर-टेस्ट के समान पैकेज है, जो इन कार्यान्वयन विवरणों तक पहुँच सकता है

उदाहरण

  public class MyClass {
    public MyClass() {
        this(new MyDependency());
    }

    /* package level to allow junit-tests to insert mock/fake implementations */ 
    MyClass(IDependency someDepenency) {...}
  }

यह "अच्छा" उपयोग है या नहीं, लेकिन यह व्यावहारिक है पर बहस करने योग्य है


2
मैं हमेशा एक अलग पैकेज में परीक्षण करता हूं, अन्यथा मुझे लगता है कि मैंने डिफ़ॉल्ट गुंजाइश में कुछ महत्वपूर्ण विधि छोड़ दी है जो किसी और को इसे कॉल करने की अनुमति नहीं देता है ...
soru

मैं इसे तरीकों से कभी नहीं करता, लेकिन यह इंजेक्शन की निर्भरता के लिए उपयोग करने के लिए एक अच्छी सुविधा है। उदाहरण के लिए, जब EJBs का परीक्षण किया जाता है, तो EntityManagers को एक पैकेज स्तर EM सेट करके मॉक ऑब्जेक्ट के साथ मॉक किया जा सकता है जहां यह रनटाइम पर एप्लिकेशन सर्वर द्वारा इंजेक्ट किया जाएगा।
विगत

protectedपैकेज-स्कोप को क्यों बढ़ाया ? protected पहले से ही पैकेज पहुंच की आपूर्ति करता है। यह एक अजीब विचित्रता है, लेकिन मुझे लगता है कि वे यौगिक गुंजाइश घोषणाओं protected packagescope void doSomething()( जैसे कि एक नए कीवर्ड की आवश्यकता भी है) की आवश्यकता नहीं करना चाहते थे ।
tgm1024 - मोनिका ने

2

यह सब उपयोगी नहीं है, खासकर एक डिफ़ॉल्ट के रूप में, एक ऐसी दुनिया में जहां लोग पैकेजों के डॉटेड नामों का उपयोग करते हैं जैसे कि वे उप-पैकेज थे। क्योंकि Java में सब-पैकेज जैसी कोई चीज नहीं है, इसलिए xyinternals के पास xy से अधिक पहुंच नहीं है, क्योंकि यह पैकेज के नाम या तो समान है या अलग है, एक आंशिक मैच आम में कुछ भी नहीं होने से अलग नहीं है।

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

जावा 9 इसे संबोधित करने का एक प्रकार है, जिसमें आप एक मॉड्यूल में कई पैकेज डाल सकते हैं और केवल कुछ निर्यात कर सकते हैं। लेकिन इससे पैकेज का दायरा और भी बेमानी हो जाएगा।

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


मुझे लगता है कि जावा 9 टिप्पणी दिलचस्प है। मुझे लगता है कि पैकेज की विरासतों को पहचानने की एक सरल क्षमता है और किसी भी तरह कुछ मूल पैकेज (एनोटेशन का उपयोग करके) के सापेक्ष पैकेज गुंजाइश को परिभाषित करना अच्छा होगा।
dsollen

1
@dsollen, शायद, लेकिन मेरा पहला झुकाव यह है कि हम उस एक के साथ टायर लोहा को सोना-प्लेट करना शुरू कर देंगे। मेरी राय में स्पष्टता के लिए एक बेहतर कदम (जो कुछ हद तक सुरक्षा लाता है) एक वास्तविक पैकेज स्कोप कीवर्ड का आविष्कार करना होगा। यह "पैकेज" भी हो सकता है :)
tgm1024 - मोनिका के

2

आपके वर्णन के सामंजस्य का प्रकार वास्तव में सबसे अच्छा उदाहरण नहीं है जहां आप पैकेज एक्सेस का उपयोग करेंगे। पैकेज घटकों, मॉड्यूल को बनाने के लिए आसान है जो एक इंटरफ़ेस पर विनिमेय हैं।

यहाँ एक परिदृश्य का एक मोटा उदाहरण है। मान लीजिए कि आपका कोड कार्यात्मक सामंजस्य और संघटन के आसपास अधिक होने के लिए पुनर्गठित किया गया था। शायद 3 जार जैसे:

**MissionManager.jar** - an application which uses the Java Service Provider Interface to load some implementation of missions, possible provided by a 3rd party vendor.

**missions-api.jar** - All interfaces, for services and model
    com...missions
        MissionBuilder.java   - has a createMission method
        Mission.java - interface for a mission domain object
    com...missions.strategy
        ... interfaces that attach strategies to missions ...
    com...missions.reports
        .... interfaces todo with mission reports ....

   **MCo-missionizer-5000.jar** -  provides MCo's Missionizer 5000 brand mission implementation.
       com...missions.mco
                  Mission5000.java - implements the Mission interface.
       com...missions.strategy.mco
              ... strategy stuff etc ...

Mission5000.java में पैकेज स्तर का उपयोग करके, आप यह सुनिश्चित कर सकते हैं कि कोई अन्य पैकेज, या घटक जैसे कि मिशन मैनजर, ​​युगल को मिशन इम्प्लिमेंटेशन से तंग नहीं कर सकता है। यह केवल "3 पार्टी" है जो "एम सह" से घटक प्रदान करता है वास्तव में एक मिशन के विशेष ब्रांडेड कार्यान्वयन का निर्माण करता है। मिशन प्रबंधक को MissionBuiler.createMission (...) को कॉल करना चाहिए और परिभाषित इंटरफ़ेस का उपयोग करना चाहिए।

इस तरह यदि मिशन कार्यान्वयन घटक को बदल दिया जाता है, तो हम जानते हैं कि MissionManager.jar के कार्यान्वयनकर्ताओं ने एपी को बायपास नहीं किया और सीधे एमसीओ के कार्यान्वयन का उपयोग किया।

इसलिए हम प्रतिस्पर्धी उत्पाद के साथ MCo-missionizer5000.jar को स्वैप कर सकते हैं। (या मिशन प्रबंधक के परीक्षण के लिए शायद एक नकली)

इसके विपरीत MCo अपने मालिकाना मिशनरी व्यापार रहस्यों को छिपाने की कुछ राशि कर सकता है।

(यह संबंधित घटकों में अस्थिरता और सार विचारों को लागू करने से संबंधित है ।)


-1

क्योंकि जावा में पैकेज स्कोप को पदानुक्रमित तरीके से डिज़ाइन नहीं किया गया है, यह शायद ही उपयोगी है। हम पैकेज गुंजाइश का उपयोग नहीं करते हैं और सभी वर्गों को सार्वजनिक रूप से परिभाषित करते हैं।

इसके बजाय हम पैकेज पदानुक्रम और पूर्वनिर्धारित पैकेज नामों के आधार पर अपने स्वयं के एक्सेस नियमों का उपयोग करते हैं।

यदि आप "CODERU-Rules" के लिए विवरण Google में रुचि रखते हैं।

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