2009-08-04 16 views
11

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

  • Hardcode गुण प्रत्येक वर्ग में फ़ाइल नाम, और फिर एक FileInputStream से लोड करने के लिए है, जो समस्या हो सकती है किसी के गुणों फ़ाइल का नाम बदलने का फैसला करता है, तो Properties वर्ग का उपयोग , क्योंकि यह कोड में हार्डकोड किया गया है।

    public class A { 
        public A() { 
         Properties p = new Properties().load(
           new FileInputStream("properties/Aconfig.properties")); 
         String value = p.getProperty("key", ""); 
        }   
    } 
    
  • एक विधि है कि, एक वर्ग के नाम को देखते हुए लोड करता है वर्ग के रूप में एक ही नाम है कि एक गुण फ़ाइल बनाएँ। यद्यपि इस दृष्टिकोण को गुण फ़ाइल नाम को हार्डकोड करने की आवश्यकता नहीं है, लेकिन यह आवश्यक है कि हम फ़ाइलों को नाम देने में कुछ सम्मेलन का पालन करें, जो भ्रम पैदा कर सकता है।

    public class A { 
        public A() { 
         Properties p = PropertiesHelper.loadFromClassName(A.class.getName()); 
         // here, we **assume** that there is a A.properties file in the classpath. 
        } 
    } 
    

हालांकि, कई अन्य अधिक सुरुचिपूर्ण दृष्टिकोण हो सकता है, और यही कारण है मैं इन सवाल पूछे है: i) जावा में लोड हो रहा है गुण फ़ाइलों के लिए सर्वोत्तम प्रथाओं हैं ?; ii) क्या आप किसी भी सहायक वर्ग का उपयोग करते हैं जो नौकरी का ख्याल रखता है ?; iii) कहां (कोड में) क्या आप आमतौर पर गुण फ़ाइल लोड करते हैं?

साथ ही, क्या कक्षा के लिए अपनी संपत्तियों को "स्वतः लोड" करना ठीक है? या मुझे उन तर्कों को पारित करना चाहिए जिन्हें मुझे निर्माता को चाहिए? तर्कों को पारित करने की समस्या यह है कि कुछ वर्गों के लिए बहुत कुछ रास्ता है (~ 20, जो एक सांख्यिकीय मॉडल में पैरामीटर का प्रतिनिधित्व करते हैं)।

उत्तर

7

सबसे अच्छा अभ्यास dependency injection कंटेनर किसी तरह का उपयोग करने के लिए हो सकता है - उदाहरण के Spring Framework या Google Guice के लिए।

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

यह संपत्ति लोडिंग के अतिरिक्त कई अन्य चीजों के साथ भी मदद करता है :-) - इसे आज़माएं, और आपको आश्चर्य होगा कि आप कभी भी कैसे रहते थे।

अद्यतन: संयोग से, your other question उन चीजों में से एक है जो वसंत का ख्याल रखेगा।

अद्यतन # 2: मैं सिर्फ महसूस किया कि मैं आप :-) पर already tried to push Spring है अपने आप को दोहरा का खतरा कम, वसंत वास्तव में यहाँ अमूर्त के साथ मदद मिलेगी। आप अपनी संपत्ति फ़ाइलों में जो स्टोर करते हैं उसके आधार पर आपको उनकी आवश्यकता नहीं हो सकती है (यदि वे कॉन्फ़िगरेशन से निपटते हैं) या आपको उनके साथ निपटने के लिए एक बहुत अच्छा एपीआई मिलेगा (यदि वे संसाधन बंडल या कुछ समान हैं)।

+0

हां:), मैं उस विशेष समस्या के लिए एसएफ का उपयोग करने पर विचार कर रहा हूं। हालांकि, इसके लिए, मैं चाहता हूं कि गुण फ़ाइलों को आसानी से कॉन्फ़िगर किया जा सके/हर किसी के द्वारा बदला जा सके (आवश्यक रूप से कंप्यूटर प्रोग्रामर नहीं), इसलिए एक सरल "कुंजी = मान"-आधारित फ़ाइल स्कीमा की आवश्यकता है। –

+0

आप अभी भी बहुत कुछ कर सकते हैं। वसंत में एक बहुत अच्छा संसाधन अबास्ट्रक्शन लेयर है: http://static.springsource.org/spring/docs/2.5.x/reference/resources.html जो आपको उन वर्ग फ़ाइलों को "जैसा है" के साथ आपकी कक्षाओं को टाइप किए बिना सौदा करने देगा उन्हें सीधे। – ChssPly76

+0

हम्म, मैं इसके बारे में पढ़ने जा रहा हूं, धन्यवाद। मैंने सोचा कि आप तत्व के अंदर संदर्भित कर रहे थे। आपके प्रश्न के लिए, मैं मूल रूप से इसमें कई मॉडल पैरामीटर संग्रहीत करता हूं (उदा।, संख्याऑफट्रियल = 50, एट कैटर [संख्यात्मक मान])। –

0

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

इस बारे में अच्छी बात यह है कि मानक है, लेकिन वे कमांड लाइन तर्क का उपयोग करके अपने स्थान/नाम को ओवरराइड कर सकते हैं।

हालांकि मेरे 2 सेंट हालांकि।

1

गुण फ़ाइलों के लिए कई जगहें हैं और उन्हें एक ही गुण वस्तु में लोड करें (एक के बाद एक)। यह योजना मैपिंग को एक डिफ़ॉल्ट मान रखने की अनुमति देती है जिसे कई बिंदुओं पर ओवरराइड किया जा सकता है।

1

फ़ाइल नाम आसानी से ऐप के लिए कमांड लाइन में पास किए जा सकते हैं। यह -D flag का उपयोग कर arg to the main method (मुख्य श्रेणी के नाम के बाद) या एक संपत्ति के रूप में किया जा सकता है (जैसा कि एपर्किन्स संकेत दे रहा है, मुझे विश्वास है)।

+0

मुझे इसके बारे में पता है, लेकिन मुझे वेब एप्लिकेशन में भी काम करने के लिए अपने आवेदन की ज़रूरत है। साथ ही, मेरे पास पास होने के लिए कई सारे फ़ाइल नाम हैं, और मुझे उस विधि का उपयोग करते हुए हर बार एक रन बनाने के लिए अपनी run.sh (या समान) स्क्रिप्ट को बदलना होगा। –

+0

यदि आपने अपने फ़ाइल नामों को कड़ी मेहनत की है, तो आप एक समान स्थिति में होंगे। आपके पास कमांडलाइन पर एक फ़ाइल नाम हो सकता है जिसमें आपको आवश्यक कॉन्फ़िगरेशन फ़ाइलों की एक सूची शामिल है। – akf

0

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

आप देख सकते हैं PropertyResourceBundle पर जिसमें अच्छी अतिरिक्त सुविधा है जो लोकेल-जागरूक है, इसलिए आप अलग-अलग लोकेल सेटिंग्स के साथ अलग-अलग गुणों को परिभाषित कर सकते हैं। ध्यान दें कि lalen या i18n मुद्दों, उदाहरण के लिए पैरामीटर को स्वतंत्र रूप से प्रदान करने के लिए लोकेल का दुरुपयोग किया जा सकता है। मैंने एक प्रोजेक्ट पर "विंडोज़" और "लिनक्स" लोकेल का इस्तेमाल किया, क्योंकि आप अपना खुद का लोकेल इंस्टेंस बना सकते हैं और इसे लोडर को पास कर सकते हैं।

या फिर आप पथ अपने आप को निर्माण कर सकते हैं ...

या आप एक इनपुट स्ट्रीम से अपने गुण लोड कर सकते हैं:

 Properties prop = Properties.load(getClass().getResourceAsStream("/myprops")); 

HTH।

+0

के माध्यम से सेट '' वसंत अच्छा है लेकिन शायद इस तरह की एक साधारण सुविधा के लिए थोड़ा सा ओवरकिल है। आप पिकोकॉन्टेनर पर एक नज़र डाल सकते हैं जो वसंत की तुलना में थोड़ी अधिक हल्की है, जहां तक ​​डीआई – insitu

+0

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

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

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