2009-02-26 19 views
8

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

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

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

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

सामान्यतः, अन्य जावा प्रोग्रामर अपनी प्राथमिकताओं को केंद्रीकृत वर्ग के साथ प्रबंधित करते हैं?

क्या सार्वजनिक एपीआई के हिस्से के रूप में उस स्थिर प्रीफ प्रबंधन वर्ग को वितरित करने के लिए यह समझ में आता है?

क्या प्रीफ़ मैनेजर डिफ़ॉल्ट निर्धारित करने के लिए कोड का रखरखाव होना चाहिए?

उत्तर

11

आईएमएचओ, मुझे लगता है कि आपके पहले प्रश्न का उत्तर "हां" और "नहीं" है।

प्राथमिकताएं आमतौर पर केंद्रीकृत वर्ग के रूप में संभाली जाती हैं, इस अर्थ में कि इस परियोजना में कक्षा कई वर्गों के लिए "सिंक" है। इसे कॉलिंग कोड के करीब करने का प्रयास करने का अर्थ है कि यदि वही वरीयता बाद में कहीं और उपयोगी होती है, तो आप परेशानी में हैं। मेरे अनुभव में, वरीयताओं को "बहुत करीब" रखने की कोशिश करने से भी एक बहुत ही असंगत हैंडलिंग में परिणाम मिलता है।

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

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

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

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

+0

वाह; बहुत बढ़िया जवाब। मेरे पास शायद 10% के साथ मामूली quibbles है, लेकिन संबंधित prefs का विभाजन एक अच्छा फोन था, और एक मुझे सोचा था। –

+0

मुझे अक्सर एक ही समस्या का सामना करना पड़ता है (हालांकि सौभाग्य से ग्रहण मुझे कई विकल्प नहीं देता है), मुझे आपकी quibbles सुनने में दिलचस्पी होगी :) – Uri

+0

साझा प्रबंधक उदाहरण प्राप्त करने के लिए - मैं वास्तव में किसी भी लॉकिंग के बारे में चिंतित नहीं था डिस्क लेखन स्तर (जो जावा हैंडल) पर, लेकिन निश्चित रूप से उच्च स्तर का अमूर्तता है, मुझे एहसास है कि मुझे भी चिंतित होना चाहिए। –

4

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

या क्या मैं इसे बहुत सरल बना रहा हूं?

+0

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

1

आप प्रेरणा के लिए कोको के NSUserDefaults कक्षा को देखना चाह सकते हैं। यह डोमेन नामक वरीयताओं की कई परतों के द्वारा वर्णित समस्या को संभालता है। जब आप किसी कुंजी के मान को देखते हैं, जैसे "PrintUsingAllCaps", यह पहले उपयोगकर्ता के स्थानीय डोमेन में किसी मान के लिए जांच करता है। यदि यह वहां नहीं मिला है, तो यह सिस्टम-व्यापी डोमेन, या नेटवर्क-स्तरीय डोमेन, और इसी तरह की जांच कर सकता है।

पूर्ण अंतिम स्थान जिसे यह चेक करता है उसे "पंजीकरण डोमेन" कहा जाता है, जो मूल रूप से हार्ड कोड वाले डिफ़ॉल्ट होने जाते हैं। इसलिए, मेरे कोड में किसी भी समय, मैं पंजीकरण डोमेन में वरीयता लिख ​​सकता हूं, और NSUserDefaults केवल उस मान को ही प्रदान करेगा यदि उपयोगकर्ता ने इसे ओवरराइड नहीं किया है।

तो, आपके मामले में, आप कक्षाओं के लिए (संभवतः) उपयोगकर्ता परिभाषित मान तक पहुंचने से पहले कुंजी के लिए डिफ़ॉल्ट मान सेट करने के लिए एक विधि प्रदान कर सकते हैं। वरीयता वर्ग को कक्षाओं के बारे में कुछ भी नहीं पता है।

जैसा कि किसी और ने सुझाव दिया है, अगर आपको कुछ और परिष्कृत की आवश्यकता है, तो आप सीधे मूल्य के बजाय DefaultValueProvider कॉलबैक ऑब्जेक्ट सेट कर सकते हैं।

2

मैं कोई जावा देव नहीं हूं, लेकिन जहां तक ​​पूरी "ऑक्टोपस क्लास" चीज जाती है, क्या आप जार में इंटरफेस की आपूर्ति नहीं कर सकते हैं और रनटाइम पर इंटरफ़ेस और प्रीफ़्स मैनेजर के बीच कॉल कनेक्ट कर सकते हैं तत्काल करने के लिए prefs प्रबंधक निर्धारित करने के लिए अनुप्रयोग विन्यास फाइल?

.NET प्रदाता पैटर्न की तरह कुछ?

इस तरह आप अपने जार को prefs प्रबंधक से decouple कर सकते हैं।

0

मैंने अपना पहला जवाब हटा दिया क्योंकि मैंने गलत समझा कि लेखक क्या पूछ रहा था।

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

क्या आप उस क्षेत्र के पैटर्न के अनुसरण वाले प्रत्येक क्षेत्र के लिए प्राथमिकता कंटेनर कक्षा का उपयोग करके दोनों आवश्यकताओं को पूरा कर सकते हैं, लेकिन इसे "ग्लोबल" वरीयता ऑब्जेक्ट संग्रह के साथ पंजीकृत कर सकते हैं?

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

एकमात्र समस्या जो मैं देख सकता हूं वह यह है कि अगर आप वरीयता ऑब्जेक्ट को तुरंत पंजीकृत करने की अनुमति देते हैं, तो आप कुछ प्राथमिकताओं के साथ "डिफ़ॉल्ट पर रीसेट" करने का प्रयास करते हैं, जो अभी तक तत्काल नहीं हैं।

मुझे लगता है कि यह मुख्य "वरीयता" वर्ग को अन्य सभी को तत्काल स्थापित करके तय किया जा सकता है, फिर कोड का कोई भी टुकड़ा केंद्रीय स्थानीय से एक स्थानीय गेटर को पुनर्प्राप्त कर सकता है।

ऐसा लगता है कि कुछ लॉगर्स कैसे काम करते हैं।लॉग स्तर, आउटपुट स्ट्रीम और ऐसे बनाए रखने के लिए एक केंद्रीय तंत्र है, लेकिन प्रत्येक वर्ग में इसका "लॉग" विधि का स्वयं का उदाहरण होता है और इसमें लॉग इन होता है।

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

0

जेएसआर -10 (java.util.prefs.*) एपीआई Preferences उदाहरण बनाने के लिए Class<?> पैरामीटर के साथ एक फैक्टरी विधि का उपयोग करता है। इस तरह एपीआई एक ही फाइल से संबंधित एक ही पैकेज से संबंधित विभिन्न वर्गों से वरीयताओं को स्टोर कर सकता है।

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