2008-12-08 13 views
9

यदि किसी ऑब्जेक्ट में कोई संपत्ति है जो संग्रह है, तो क्या ऑब्जेक्ट संग्रह ऑब्जेक्ट बना सकता है या उपभोक्ता चेक को नल के लिए बना सकता है? मुझे पता है कि उपभोक्ता को यह नहीं मानना ​​चाहिए, बस सोच रहा है कि ज्यादातर लोग संग्रह वस्तु बनाते हैं यदि इसे कभी जोड़ा नहीं जाता है।किसी ऑब्जेक्ट के भीतर संग्रह प्रारंभ करें?

उत्तर

7

आप "आलसी initailizer" पैटर्न का भी उपयोग कर सकते हैं जहां संग्रह प्रारंभ नहीं किया जाता है (और जब तक) कोई इसके लिए संपत्ति गेटटर तक नहीं पहुंचता है ... यह उन मामलों में इसे बनाने के ऊपरी हिस्से से बचाता है जहां मूल वस्तु है किसी अन्य उद्देश्य के लिए तत्काल किया गया है जिसे संग्रह की आवश्यकता नहीं है ...

public class Division 
    { 
     private int divId; 
     public int DivisionId { get; set; } 

     private Collection<Employee> emps; 
     public Collection<Employee> Employees 
     { get {return emps?? (emps = new Collection<Employee>(DivisionId));}} 
    } 

संपादित करें: इस कार्यान्वयन पैटर्न, है सामान्य रूप में, सुरक्षित थ्रेड नहीं ... emps दो अलग धागे से अशक्त के रूप में पहले पहले धागा इसे संशोधित करना समाप्त कर पढ़ा जा सकता है। इस मामले में, शायद यह कोई फर्क नहीं पड़ता कि डिवीजन आईडी अपरिवर्तनीय है और हालांकि दोनों धागे अलग-अलग संग्रह प्राप्त करेंगे, वे दोनों मान्य होंगे। दूसरा धागा fihishes, इसलिए, emps एक वैध संग्रह होगा। 'शायद' ऐसा इसलिए है क्योंकि दूसरे थ्रेड के लिए पहले धागे को emps का उपयोग शुरू करना संभव हो सकता है, इससे पहले कि यह थ्रेड रीसेट हो जाए। वह थ्रेड-सुरक्षित नहीं होगा। जॉन स्काईट से एक और थोड़ा जटिल कार्यान्वयन थ्रेड-सुरक्षित है (This article on SIngletons को इसके उदाहरण/चर्चा के लिए इस बारे में चर्चा के लिए देखें।

+0

इस तरह से पसंद आया ... मेरी ज़रूरतों को पूरा करता है .. – CSharpAtl

+0

चीजें करने की मेरी शैली भी बनती है !! वोट + 1 – Perpetualcoder

+0

ठीक है लेकिन (1) इस बात से अवगत रहें कि आलसी प्रारंभिकरण का यह कार्यान्वयन थ्रेड-सुरक्षित नहीं है - जो तब तक ठीक है जब तक यह दस्तावेज (2) पढ़ने/लिखने की संपत्ति पर कर्मचारियों की निर्भरता डिवीजन आईडी का मतलब है गुणों को स्थापित करना महत्वपूर्ण है - एमएस दिशानिर्देशों के विपरीत। – Joe

1

मैं एक खाली संग्रह बनाते हैं। निश्चित रूप से, इसकी थोड़ी मेमोरी लागत है, लेकिन इसके बारे में चिंतित होने के लिए पर्याप्त नहीं है।

1

आईएमओ, यह वह जगह है जहां आईनेमेरेबल अच्छी तरह से आता है।

व्यक्तिगत रूप से, मुझे अपनी 'संग्रह' गुणों को खाली सूचियों में आरंभ करने के लिए पसंद है।

3

यह आपके एपीआई और उपयोगकर्ता के बीच आपके अनुबंध पर निर्भर करता है।

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

यानी, setFooSet (सेट सेट) के बजाय addFoo (Foo toAdd), और इसी तरह।

लेकिन यह आपके ऊपर है।

2

मैं आमतौर पर संग्रह बनाउंगा, फिर क्लास के उपभोक्ता को नल की जांच करने के बारे में चिंता करने के बजाय आंतरिक संग्रह से वस्तुओं को जोड़ने/निकालने के तरीके प्रदान करता हूं। इससे आपको संग्रह को बेहतर तरीके से नियंत्रित करने की क्षमता भी मिलती है। आखिरकार यह इस बात पर निर्भर करता है कि यह क्या है, लेकिन संभवतः यदि आपकी कक्षा में संग्रह है तो यह संभव नहीं है कि कक्षा के उपभोक्ता के पास उन वस्तुओं का संग्रह हो। अन्यथा, वे आपकी कक्षा का उपयोग क्यों करेंगे?

2

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

1

यदि संग्रह ऑब्जेक्ट का एक आंतरिक हिस्सा है, तो ऑब्जेक्ट को आम तौर पर इसे बनाना चाहिए (और उपयोगकर्ता को इसे एक अलग संग्रह उदाहरण में सेट करने की अनुमति नहीं देना चाहिए)।

1

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

2

मैं तत्कालता पर संग्रह बनाना पसंद करता हूं, युक्त ऑब्जेक्ट में जोड़ने/निकालने के तरीकों को प्रदान करना पसंद करता हूं, और यदि आवश्यक हो, तो संपूर्ण बाहरी संग्रह जोड़ने और निकालने के लिए addAll/removeAll विधियां प्रदान करें। मैं संग्रह ऑब्जेक्ट को कॉलर द्वारा प्राप्त या सेट करने के लिए कभी भी एक्सेस नहीं करने की अनुमति देता हूं - हालांकि, मैं एक गेटटर प्रदान कर सकता हूं जो संग्रह की एक प्रति (संभावित अपरिवर्तनीय) देता है।

मेरे पास कॉपी-ऑन-राइट कार्यान्वयन भी हैं जो एक अपरिपक्व रूप से लपेटा हुआ दृश्य प्रदान करते हैं, क्योंकि कोई भी उत्परिवर्तन एक नया अंतर्निहित संग्रह तैयार करेगा।

0

एक सामान्य नियम के रूप में, मुझे लगता है कि ऑब्जेक्ट को संग्रह बनाना चाहिए और इसे कुशल बनाने के तरीकों को प्रदान करना चाहिए; जोड़ें/प्राप्त/निकालें। इस नियम का पालन करते समय, आपको संग्रह को सीधे सेट करने के तरीकों को प्रदान नहीं करना चाहिए। यदि आप सुविधा के लिए setSomeCollection (संग्रह कुछ संग्रह) जैसी विधि चाहते हैं, तो इस विधि के कार्यान्वयन को ऑब्जेक्ट के भीतर संदर्भ सेट नहीं करना चाहिए, लेकिन ऑब्जेक्ट के भीतर संग्रह पैरामीटर संग्रह से मानों की प्रतिलिपि बनाएँ;

public void setSomeCollection(Collection someCollection) { 
    this.someCollection.clear(); 
    this.someCollection.addAll(someCollection); 
} 

आपको यह करना चाहिए, इसलिए आपके एपीआई के क्लाइंट आपके क्लास को बनाए रखने वाले संग्रह तक पहुंच नहीं प्राप्त कर सकते हैं। यदि वे करते हैं, तो वे आपकी कक्षा की वस्तुओं का उपयोग किए बिना इसे कुशल बना सकते हैं और आपकी कक्षा की गारंटी की बाधाओं का उल्लंघन कर सकते हैं।

एक गेटर प्रदान करने पर भी यही सच है; आपको या तो अपने आंतरिक कोलेसिटन की प्रतिलिपि या इसके केवल पढ़ने के संस्करण को वापस करना चाहिए। अपाचे कॉमन्स-संग्रह और Google-संग्रह संग्रह के आस-पास अपरिवर्तनीय रैपर बनाने के लिए विधियां प्रदान करते हैं, साथ ही जावा के साथ java.util पैकेज में आने वाले तरीकों को भी प्रदान करते हैं; java.util.Collections.unmodifiable *।

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