2012-11-30 27 views
6

पहले ही पढ़ कैसे निम्न चरणों केअपरिवर्तनीय वर्ग/वस्तु, निजी निर्माता, कारखाने विधि

द्वारा एक वर्ग अपरिवर्तनीय बनाने के लिए होने
  1. "सेटर" तरीकों प्रदान न करें - तरीकों कि खेतों या वस्तुओं क्षेत्रों से जाना जाता संशोधित ।
  2. सभी फ़ील्ड को अंतिम और निजी बनाएं।
  3. उपclasses विधियों को ओवरराइड करने की अनुमति न दें। ऐसा करने का सबसे आसान तरीका कक्षा को अंतिम घोषित करना है। एक और परिष्कृत दृष्टिकोण रचनाकार निजी बनाने और कारखाने के तरीकों में उदाहरण बनाने के लिए है।
  4. यदि उदाहरण फ़ील्ड में म्यूटेबल ऑब्जेक्ट्स के संदर्भ शामिल हैं, तो उन ऑब्जेक्ट्स को बदलने की अनुमति न दें:
    ए। म्यूटेबल ऑब्जेक्ट्स को संशोधित करने वाली विधियां प्रदान न करें।
    बी। म्यूटेबल ऑब्जेक्ट्स के संदर्भ साझा न करें। कभी भी कन्स्ट्रक्टर को पारित बाहरी, परिवर्तनीय वस्तुओं के संदर्भों को संग्रहीत न करें; यदि आवश्यक हो, प्रतियां बनाएं, और प्रतियों को स्टोर संदर्भ दें। इसी तरह, अपनी विधियों में मूल लौटने से बचने के लिए आवश्यक होने पर अपनी आंतरिक परिवर्तनीय वस्तुओं की प्रतियां बनाएं।

AM मुझे यकीन नहीं है कि मैं अपरिवर्तनीयता के संदर्भ में निजी कन्स्ट्रक्टर और फैक्ट्री विधि की उपयोगिता को स्पष्ट रूप से समझता हूं। यदि मैं कक्षा फाइनल बनाता हूं, मूल रूप से इसे विस्तारित किसी भी अन्य वर्ग के सभी पथ बंद कर रहा हूं। कैसे एक और अधिक परिष्कृत दृष्टिकोण

मैं निजी निर्माता, सिंगलटन पैटर्न जो समझ में आता है में कारखाने विधि देखा है कहा गया है। लेकिन जब हम ऑब्जेक्ट अपरिवर्तनीयता की बात करते हैं, तो क्या हम निजी निर्माणकर्ता और स्थैतिक फैक्ट्री विधियों का जिक्र करते समय ऑब्जेक्ट निर्माण/तत्कालता को भी सीमित कर रहे हैं ??

+0

हां। उदाहरण (2) और (4) उदाहरण अपरिवर्तनीय बनाने के लिए पर्याप्त होना चाहिए। करना (3) कक्षा को विस्तार करना असंभव बनाता है (या कम से कम, कोई उप-वर्ग तत्काल नहीं होगा), जो पूरी तरह से अलग है। –

उत्तर

0

हाँ, आप सही हैं। यह कन्स्ट्रक्टर निजी बनाने के लिए कोई मतलब नहीं है। ऐसा करके, हम उदाहरण निर्माण को सीमित कर रहे हैं, जो अपरिवर्तनीयता के लिए वांछित परिदृश्य नहीं है।

उदाहरण में सूरज साइट में उल्लेख निजी http://docs.oracle.com/javase/tutorial/essential/concurrency/syncrgb.html

+0

यह एक सिंक्रनाइज़ क्लास उदाहरण है .. मुझे लगता है कि आपका मतलब है http://docs.oracle.com/javase/tutorial/essential/concurrency/imstrat.html – HungryForKnowledge

+0

सही ... हालांकि कक्षा अपरिवर्तनीय है, लेकिन उन्होंने कम नहीं किया कन्स्ट्रक्टर की दृश्यता। मुझे लगता है कि कन्स्ट्रक्टर निजी बनाने से कोड में ओवरहेड बढ़ जाएगा। – Vishal

-1

निर्माता है ऐसा इसलिए है क्योंकि निजी निर्माता के साथ हम इसके बारे में एक उपवर्ग नहीं कर सकते हैं, और इस तरह किसी भी अन्य वर्ग इसे विस्तार के सभी रास्तों को सीमित नहीं है। यह परिष्कृत है क्योंकि इसकी अपनी सीमाएं/जटिलताओं जैसे सिंगलटन पैटर्न में हैं।

+0

अंतिम कक्षा को बढ़ाया नहीं जा सकता है। : - (... तो आप कक्षा को इसे अंतिम रूप से बढ़ाकर सीमित कर देंगे ... – Vishal

+0

हां, यही कारण है कि अंतिम बनाना सबसे आसान तरीका है, और कन्स्ट्रक्टर निजी बनाना अधिक परिष्कृत दृष्टिकोण है। –

+0

आप कैसे बनाएंगे उदाहरण? फैक्ट्री विधि का उपयोग करना, लेकिन यह कैसे सहायता करेगा? परिष्कारता कोड में जटिलताओं में नहीं है ... – Vishal

0

सबसे पहले, वहाँ कई कारण अपरिवर्तनीय वर्ग आम तौर पर ओवरराइड नहीं किया जाना चाहिए, तो आप उन्हें here पा सकते हैं।

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

+0

यदि आप सुपर क्लास में एक कन्स्ट्रक्टर निजी बनाते हैं, तो सबक्लास बनाने में कोई समझ नहीं है, है ना ?? क्योंकि यदि आपके पास सबक्लास है और आपकी सुपर क्लास में एक निजी कन्स्ट्रक्टर है, तो यह एक कम्पाइल टाइम त्रुटि के रूप में अपना कयामत देखने जा रहा है .. – HungryForKnowledge

+0

लेकिन मुझे अपरिवर्तनीयता और गैर-विस्तारशीलता के बीच एक कनेक्शन दिखाई देता है .. सब्सक्रिप्शन की शुद्धता तोड़ सकती है अपरिवर्तनीय .. कम से कम मैं यह बता सकता हूं कि आपके द्वारा पोस्ट किए गए लिंक से – HungryForKnowledge

+0

अपरिवर्तनीयता निजी रचनाकारों या फैक्ट्री विधियों से जुड़ी नहीं है। जेडीके में कई कक्षाओं में फैक्ट्री विधियों और सार्वजनिक रचनाकार दोनों हैं। –

1

अचल स्थिति - संगामिति के लिए बहुत उपयोगी है क्योंकि यह विभिन्न अपरिवर्तनीय कि सूत्रण वातावरण में संभव हो रहे हैं के निर्माण से बचा जाता है।

फैक्टरी तरीके - बस एक नामकरण परंपरा के रूप में वे अधिक वर्बोज़ को पढ़ने के लिए और उनके मनपसंद नाम से समझने में आसान कर रहे हैं। उदाहरण के लिए: copyOf() विधि एक कॉपी कन्स्ट्रक्टर बनाने से अधिक समझदारी होगी। प्रभावी जावा

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

1

मुझे लगता है कि यहां बड़ा मुद्दा भविष्य में रिफैक्टरिंग है। मान लीजिए, बाद के संस्करण में, आपको लगता है कि यह कुछ आसान बना देगा यदि आप MyClass के कुछ नए विशेष मामले को सबक्लास, MySpecialClass में विभाजित कर सकते हैं।

यदि MyClass एक सार्वजनिक कन्स्ट्रक्टर के साथ एक उत्परिवर्ती वर्ग था, तो आप बस इसे कर सकते हैं और नए MySpecialClass बनाने के लिए नई सुविधाओं के उपयोगकर्ताओं को बता सकते हैं। मौजूदा उपयोग प्रभावित नहीं हैं।

यदि MyClass का निजी कन्स्ट्रक्टर और फैक्ट्री विधि है, तो कोई समस्या नहीं है। आप MyClass में निहित MySpecialClass को भी निजी कन्स्ट्रक्टर के साथ घोषित करते हैं। कौन सा निर्माण करना है, यह चुनने के लिए कारखाने के तरीकों को जोड़ें और/या संशोधित करें, लेकिन सुनिश्चित करें कि मौजूदा कॉल संगत रूप से काम करने पर चलती हैं।

यदि MyClass अपरिवर्तनीय और अंतिम था, लेकिन सार्वजनिक कन्स्ट्रक्टर था तो आप क्या करेंगे?

+0

मुझे लगता है कि यदि MyClass MySpecialClass का सुपर क्लास है, तो MyClass के संरक्षक को संरक्षित करने की आवश्यकता नहीं है? – HungryForKnowledge

+0

धन्यवाद - मैं अपना उत्तर सही कर दूंगा - MySpecialClass को एक निजी कन्स्ट्रक्टर तक पहुंचने के लिए, MyClass में घोषित करने की आवश्यकता है, साथ ही इसे विस्तारित करने की आवश्यकता है। –

0

से प्रभावी जावा मद 15 मेरे अपने निष्कर्षों में से कुछ, एक ही

से प्रासंगिक बयानों चिपकाने "याद है कि अचल स्थिति की गारंटी करने, एक वर्ग ही आमतौर पर अनुमति नहीं चाहिए subclassed किया जाना है। यह हो जाए कक्षा को अंतिम बनाकर, लेकिन ऐसा करने के लिए एक और अधिक लचीला तरीका है। एक अपरिवर्तनीय कक्षा फाइनल बनाने का विकल्प अपने रचनाकारों को निजी या पैकेज-निजी बनाने और स्थान पर सार्वजनिक स्थैतिक कारखानों को जोड़ने के लिए है सार्वजनिक रचनाकारों (आइटम 1) का।

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

"

स्थिर कारखाने बनाम निर्माता फायदे तो चर्चा कर रहे हैं

+0

वह अपने दावे को औचित्य कैसे देता है, कि "अपरिवर्तनीयता की गारंटी के लिए, एक वर्ग को खुद को उप-वर्गीकृत करने की अनुमति नहीं देनी चाहिए"? –

+0

@ जावाविडवेस प्रभावी जावा से दाएं, कक्षा को अपरिवर्तनीय बनाने के नियमों में से एक को बताते हुए 2. सुनिश्चित करें कि कक्षा को बढ़ाया नहीं जा सकता है। यह उप-वर्गों को का व्यवहार करके कक्षा के अपरिवर्तनीय व्यवहार से समझौता करने से लापरवाही या दुर्भावनापूर्ण को रोकता है जैसे ऑब्जेक्ट की स्थिति बदल गई है। क्लास फाइनल बनाकर सबक्लासिंग को रोकना आम तौर पर पूरा किया जाता है, लेकिन एक विकल्प है कि हम बाद में चर्चा करेंगे। स्पष्ट रूप से निजी कन्स्ट्रक्टर, कारखाना विधि वैकल्पिक – HungryForKnowledge

+0

है लेकिन सभी क्षेत्रों को अंतिम और निजी बनाने से गंदे उप-वर्गों को गंदा चीजें करने से रोक दिया जाएगा। यह मुझे ओवरकिल की तरह लगता है। –

0

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

उदाहरण

public class Temperature 
{ 
    private readonly double temperatureInCelsius; 

    public Temperature(string temperatureInCelsius) 
    { 
     this.temperatureInCelsius = System.Convert.ToDouble(temperatureInCelsius); 
    } 
    private Temperature(double temperatureInCelsius) 
    { 
     this.temperatureInCelsius = temperatureInCelsius; 
    } 

    public Temperature AddCelsius(string temperatureToAddInCelsius) 
    { 
     return new Temperature(System.Convert.ToDouble(temperatureToAddInCelsius) + temperatureInCelsius); 
    } 
    public void PrintCelsius(Display display) 
    { 
     display.Print(temperatureInCelsius); 
    } 
    public void PrintFarenheit(Display display) 
    // ... etc 
} 

, उदाहरण के अर्द्ध मूर्खता की उपेक्षा करता है, तो अपनी आवश्यकताओं के उस वर्ग एक स्ट्रिंग तापमान का प्रतिनिधित्व करने से निर्माण किया जा सकता हैं

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

+0

पैकेज-प्राइवेट कन्स्ट्रक्टर का उपयोग करने का एक मौलिक लाभ यह है कि एक सार्वजनिक कन्स्ट्रक्टर के साथ एक वर्ग 'फू' का वादा करता है कि 'नया फू (जो भी)' कॉल करने वाला कोड एक नया ऑब्जेक्ट उदाहरण प्राप्त करेगा और इसका सटीक प्रकार 'फू' होगा, लेकिन कई अपरिवर्तनीय कक्षाएं ऐसा वादा नहीं करना चाहती हैं। यदि एक वर्ग लेखक जो एक ही तापमान के लिए कई अनुरोधों की अपेक्षा करता है, उसमें स्थिर 'वीकैक्सी <स्ट्रिंग, तापमान>' शामिल हो सकता है, तो उसी स्ट्रिंग के साथ दोहराए गए अनुरोध समान तापमान प्राप्त करेंगे। एक सार्वजनिक कन्स्ट्रक्टर का पर्दाफाश करना असंभव होगा। – supercat

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