2009-08-16 10 views
9

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

उत्तर

5

अपरिवर्तनीय कक्षाएं वस्तु प्रसार को बढ़ावा देने के करते हैं, लेकिन अगर आप सुरक्षा चाहते हैं, परिवर्तनशील वस्तुओं अधिक वस्तु प्रसार को बढ़ावा देंगे, क्योंकि आप नहीं बल्कि मूल वस्तु तुम वापस परिवर्तित करने से उपयोगकर्ता को रोकने के लिए की तुलना में प्रतियां वापस लौटाना होगा।

सभी स्थैतिक तरीकों के साथ कक्षाओं का उपयोग करने के लिए, यह वास्तव में उन मामलों में एक विकल्प नहीं है जहां अपरिवर्तनीयता का उपयोग किया जा सकता है। इस उदाहरण को एक आरपीजी से लें:

public class Weapon 
{ 
    final private int attackBonus; 
    final private int accuracyBonus; 
    final private int range; 

    public Weapon(int attackBonus, int accuracyBonus, int range) 
    { 
     this.attackBonus = attackBonus; 
     this.accuracyBonus = accuracyBonus; 
     this.range = range; 
    } 

    public int getAttackBonus() { return this.attackBonus; } 
    public int getAccuracyBonus() { return this.accuracyBonus; } 
    public int getRange() { return this.range; } 
} 

आप इसे केवल उस वर्ग के साथ कैसे लागू करेंगे जिसमें केवल स्थिर विधियां हों?

12

immutable कक्षाओं का मुख्य लाभ यह है कि आप आंतरिक डेटा सदस्यों का खुलासा कर सकते हैं जो अपरिवर्तनीय हैं क्योंकि कॉलर उन्हें संशोधित नहीं कर सकता है। java.util.Date कहें, यह एक बड़ी समस्या है। यह उत्परिवर्तनीय है ताकि आप इसे सीधे किसी विधि से वापस नहीं कर सकें। इसका मतलब है कि आप सभी प्रकार के defensive copying कर रहे हैं। इससे ऑब्जेक्ट प्रसार बढ़ जाता है।

अन्य प्रमुख लाभ यह है कि अपरिवर्तनीय वस्तुओं में परिभाषा के अनुसार synchronization समस्याएं नहीं हैं। यही वह जगह है जहां scalability समस्याएं आती हैं। multithreaded कोड लिखना मुश्किल है। अपरिवर्तनीय वस्तुएं समस्या का निवारण (ज्यादातर) का एक अच्छा तरीका हैं।

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

स्टेटिक फैक्ट्री विधियों के अन्य लाभ हो सकते हैं। विचार वस्तु निर्माण को समाहित करना है।

+1

एक स्थिर वर्ग एक वर्ग है जिसे आप कभी भी तत्काल नहीं करते हैं, लेकिन प्रदान की गई विधियों का उपयोग करें (जैसे जावा में Arrays)। मैं नहीं देखता कि वे अपरिवर्तनीय कक्षाओं को कैसे हटा सकते हैं ... – Zed

+0

शायद "स्थिर वर्ग" यहां "अपरिवर्तनीय वर्ग" का पर्याय है। कुछ और समझ में नहीं आता है। – CPerkins

+0

"स्टेटिक क्लास" का उपयोग करना मेरा मतलब है एक वर्ग जिसमें निजी कन्स्ट्रक्टर के साथ सभी स्थैतिक विधि शामिल हैं (इसलिए उपयोगकर्ता किसी भी स्थिर सदस्य के बिना उसी वर्ग का उदाहरण नहीं बना सकता)। भ्रम पैदा करने के लिए खेद है। –

1

क्लीटस ने कहा, अपरिवर्तनीय वर्ग कक्षा के डिजाइन को सरल बनाते हैं और सिंक्रनाइज़ किए गए तरीकों में हैंडलिंग करते हैं।

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

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

0

अपरिवर्तनीयता आमतौर पर स्केलेबिलिटी प्राप्त करने के लिए उपयोग की जाती है, क्योंकि जब जावा में समवर्ती प्रोग्रामिंग की बात आती है तो अपरिवर्तनीयता enablers में से एक है। इसलिए, जैसा कि आप इंगित करते हैं, "अपरिवर्तनीय" समाधान में और अधिक वस्तुएं हो सकती हैं, यह समरूपता में सुधार के लिए एक आवश्यक कदम हो सकता है।

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

0

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

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

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

0

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

1

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

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

यह हैशैप और हैशसेट आंतरिक रूप से कैसे काम करते हैं - वे हैश कोड द्वारा ऑब्जेक्ट व्यवस्थित करते हैं।

This article जावा समेकन गुरु ब्रायन गोएट्ज द्वारा अपरिवर्तनीय वस्तुओं के पेशेवरों और विपक्ष का एक अच्छा अवलोकन प्रदान करता है।

0

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

उदाहरण के लिए:

जावा में
String A = "abc"; 
String B = "abc"; 

स्ट्रिंग ऑब्जेक्ट अपरिवर्तनीय है। अब दोनों & बी एक ही "एबीसी" स्ट्रिंग पर इंगित करते हैं। अब

A = A + "123"; 
System.out.println(B); 

यह होना चाहिए उत्पादन:

abc 

क्योंकि स्ट्रिंग अपरिवर्तनीय है, एक बस "abc123" के बजाय पुराने स्ट्रिंग वस्तु को संशोधित करने की स्ट्रिंग वस्तु नया को इंगित करेंगे।

+0

-1। ए = ए + "123" बस एक नई स्ट्रिंग (एबीसी 123) का निर्माण करेगा और इसे वैरिएबल ए स्ट्रिंग को असाइन करने योग्य है, जिसमें आप 123 स्ट्रिंग को एबीसी में नहीं बदल सकते हैं - स्ट्रिंग ऑब्जेक्ट में कोई असाइन विकल्प नहीं है। हालांकि, दो अन्य लोगों में से एक नई स्ट्रिंग ऑब्जेक्ट बनाने के लिए यह बिल्कुल ठीक है। – fwielstra

+0

खैर, एक नया स्ट्रिंग बनाया गया था, और ए नया "abc123" इंगित करेगा। यहां फोकस क्षेत्र नई वस्तु के लिए एक "बिंदु" है। मैंने यह नहीं कहा कि "abc123" मौजूदा "एबीसी" और न ही "123" के संशोधन का परिणाम था। – janetsmith

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