2010-05-25 14 views
5

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

वहाँ भाषाओं कि मेरी रुचि को संतुष्ट कर रहे हैं? शायद यह उन्हें एक भाषा का हिस्सा बनाने के लिए गूंगा है; शायद नहीं। मुझे यकीन नहीं है।

आज मैं जावा में कार्यक्रम है, लेकिन मैं के रूप में मैं चाहता हूँ उपयोग नहीं कर सकते "अंतिम" लगभग उतना ही है, क्योंकि उन चरणों होने के बाद निर्माता निष्पादन समाप्त हो गया है। जावा के साथ जो चाहते हैं उसे पाने के बारे में कोई सलाह? मुझे लगता है कि मैं अपनी ऑब्जेक्ट्स को बेस क्लास को कार्यान्वित कर सकता हूं ताकि उन चरणों को कन्स्ट्रक्टर खत्म होने से पहले हो, या ऐसा करने के लिए पहलुओं का उपयोग करें।

विचार?

उत्तर

3

मुझे लगता है कि का उल्लेख यह इस बात पर निर्भर करता है कि आप अपरिवर्तनीयता से क्या चाहते हैं। यदि आप गारंटीकृत थ्रेड सुरक्षा चाहते हैं (जहां निर्भरता समेत सभी को अंतिम घोषित किया जाना चाहिए) तो मुझे लगता है कि कारखाना, निर्माता या कन्स्ट्रक्टर इंजेक्शन आपके एकमात्र विकल्प हैं।

यदि आप केवल राज्य की अपरिवर्तनीयता चाहते हैं, तो राज्य चर अंतिम को घोषित करना पर्याप्त होना चाहिए। यहां तक ​​कि अपरिवर्तनीय स्ट्रिंग क्लास के कार्यान्वयन में एक उत्परिवर्तनीय क्षेत्र है (हैशकोड मान का कैश)। जब तक आपका कोड अन्यथा सुनिश्चित करता है कि इंजेक्शन के बिना कोई उदाहरण उपलब्ध नहीं है, तो सभी को अच्छी तरह से होना चाहिए।

+0

मैं बस यह स्पष्ट करना चाहता हूं कि कौन से सदस्य उत्परिवर्तनीय हैं और जो नहीं हैं। अजीब, लेकिन मैंने कभी सोचा नहीं कि कैसे सेटर इंजेक्शन अपरिवर्तनीय स्थिति के साथ असंगत है। खैर, मैं इस बारे में सोच नहीं रहा था जब मैंने सवाल लिखा, कम से कम :-) – Ladlestein

0

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

public void setMyProperty(String newValue) { 
    checkInitialized(); 
    myProperty = newValue; 
} 

public void checkInitialized() { 
    if (initialized) { 
     throw new IllegalStateException("Setter called after initialization"); 
    } 
} 

सबसे अच्छा हालांकि यह गतिशील जांच दे रहा है। यह आपके पास पहले से मौजूद किसी भी स्थिर प्रतिक्रिया नहीं देता है।

4

वहाँ अपरिवर्तनीय वस्तुओं के उत्पादन के दो मुख्य तरीके हैं:

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

  2. एक MutableObject उपवर्ग, जो परिवर्तनशील राज्य के लिए एक ध्वज का कहना पैदा करते हैं। कोई भी परिवर्तन करने से पहले आपके सभी म्यूटेटर म्यूटेबल स्टेटस की जांच करते हैं - यदि ऑब्जेक्ट को अपरिवर्तनीय सेट किया गया है, तो चेक अपवाद फेंकता है, अन्यथा परिवर्तन आगे बढ़ता है।

पहले दृष्टिकोण, काफी स्प्रिंग केंद्रित है, क्योंकि यह एक वसंत-विशिष्ट इंटरफेस के implmentation की आवश्यकता है। आप फैक्ट्री बीन्स बना सकते हैं जो नियमित बीन्स हैं, factory-method/factory-bean बीन पर विशेषताओं के माध्यम से, जो आपके कोड से वसंत निर्भरता को हटा देता है।

दूसरे दृष्टिकोण का उपयोग वसंत के साथ विशेष रूप से उपयोगी है। आप बीन प्रारंभिकरण के बाद एक विधि को कॉल करने के लिए वसंत को निर्देश दे सकते हैं, उदा। सील() जो ऑब्जेक्ट को सील करता है - इसे अपरिवर्तनीय बनाता है। वैकल्पिक रूप से, आप इनिट-विधि = "मुहर" सेट करने के बिना स्वचालित रूप से इसे याद रखने के लिए एक छोटे BeanFactoryPostProcessor को कार्यान्वित कर सकते हैं। प्रत्येक अपरिवर्तनीय बीन पर।

+0

आपका उत्तर सहायक है; मैंने दूसरे को चुना है क्योंकि उसने "कन्स्ट्रक्टर इंजेक्शन" कहा है, जिसने इस मुद्दे को मेरे लिए थोड़ा बेहतर बना दिया है। – Ladlestein

+0

मैं "अंतिम" या किसी अन्य भाषा में उपयोग करना चाहता हूं, जो भी तंत्र संकेत करता है और अपरिवर्तनीयता को लागू करता है। जावा में, क्या बिल्डर वास्तव में मेरी मदद करता है? अंतिम उपयोग करने के लिए आवश्यक कन्स्ट्रक्टर इंजेक्शन का उपयोग नहीं कर रहा है? – Ladlestein

+0

बिल्डर सेटर इंजेक्शन का उपयोग कर सकते हैं, और यह कन्स्ट्रक्टर इंजेक्शन का उपयोग कर ऑब्जेक्ट का उत्पादन करता है। सी.एफ़ स्प्रिंग में अधिकांश फैक्ट्रीबीन कार्यान्वयन - वे सेटटर इंजेक्शन का उपयोग करके कॉन्फ़िगर किए गए हैं। – mdma

1

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

आप स्काला का उपयोग करते हैं, हालांकि, अचल स्थिति the default है।

+0

जैसा कि मैंने उपरोक्त कहा है, बिल्डर कैसे मदद करता है, ऐसा लगता है कि बिल्डर प्रासंगिक नहीं है, जब तक कि मैं कन्स्ट्रक्टर इंजेक्शन का उपयोग नहीं कर रहा हूं। – Ladlestein

+0

बिल्कुल, यही कारण है कि मैंने कहा "सेटर्स से दूर शर्मीला"। –

0

निर्दिष्ट करने के लिए है कि एक वर्ग अपरिवर्तनीय है, तो आप @Immutable एनोटेशन का उपयोग कर सकते हैं।

आप जावाडोक here देख सकते हैं।

यह ग्रहण में Findbugs प्लगइन के साथ अच्छी तरह से काम करता है।

@Alexander:

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

एक टुकड़ा:

आवश्यकता के

इसका मतलब यह है कि सभी सार्वजनिक क्षेत्रों अंतिम हैं, और है कि सभी सार्वजनिक अंतिम संदर्भ क्षेत्रों अन्य अपरिवर्तनीय वस्तुओं

+0

-1। Aahh! क्या कोई @ @ नोबग्स एनोटेशन है? :) –

+1

उचित बिंदु। डाउनवोट हटा दिया गया। –

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