यदि कोई डेटा ऑब्जेक्ट प्रकार अपरिवर्तनीय होने के लिए डिज़ाइन किया जाना चाहिए तो यह कैसे तय करता है?


23

मैं अपनी ताकत के कारण अपरिवर्तनीय "पैटर्न" से प्यार करता हूं, और अतीत में मैंने अपरिवर्तनीय डेटा प्रकार (कुछ, सबसे या यहां तक ​​कि सभी) के साथ सिस्टम को डिजाइन करना फायदेमंद पाया है। अक्सर जब मैं ऐसा करता हूं, तो मैं खुद को कम बग लिखता हुआ पाता हूं और डिबगिंग बहुत आसान है।

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

Foo a = new Foo();
a.setProperty1("asdf");
a.setProperty2("bcde");

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

आप कैसे तय करते हैं कि किसी ऑब्जेक्ट प्रकार को अपरिवर्तनीय रूप में डिज़ाइन किया जाना चाहिए? क्या इसके द्वारा न्याय करने के लिए मापदंड का एक अच्छा सेट है?

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


1
एर्लैंग में कार्यक्रम और पूरी समस्या हल हो गई है, सब कुछ अपरिवर्तनीय है
Zachary K

1
@ZacharyK मैं वास्तव में कार्यात्मक प्रोग्रामिंग के बारे में कुछ का उल्लेख करने के बारे में सोच रहा था, लेकिन कार्यात्मक प्रोग्रामिंग भाषाओं के साथ अपने सीमित अनुभव के कारण बच गया।
Ricket

जवाबों:


27

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


11

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

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


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

-1, मैं @ 9000 से सहमत हूं। थ्रेड सेफ्टी सेकेंडरी है (ऐसी वस्तुओं पर विचार करें जो अपरिवर्तनीय दिखाई देती हैं लेकिन उदाहरण के संस्मरण के कारण उनमें आंतरिक परिवर्तनशील स्थिति होती है)। इसके अलावा, उत्परिवर्तनीय प्रदर्शन को लाना समय से पहले का अनुकूलन है, और यदि आपको आवश्यक है कि उपयोगकर्ता "यह जान लें कि वे क्या कर रहे हैं" तो कुछ भी बचाव करना संभव है। अगर मुझे पता था कि मैं हर समय क्या कर रहा हूं, तो मैं बग के साथ एक कार्यक्रम कभी नहीं लिखूंगा।
डोभाल

4
@ डोभाल: इस बात से कोई असहमत नहीं है। 9000 बिल्कुल सही है; अपरिवर्तनीय वस्तुओं रहे हैं के बारे में कारण करने के लिए आसान। यह आंशिक रूप से है जो उन्हें समवर्ती प्रोग्रामिंग के लिए इतना उपयोगी बनाता है। दूसरा हिस्सा यह है कि आपको राज्य बदलने की चिंता नहीं है। समयपूर्व अनुकूलन यहाँ अप्रासंगिक है; अपरिवर्तनीय वस्तुओं का उपयोग डिजाइन के बारे में है , प्रदर्शन के बारे में नहीं, और डेटा संरचनाओं का खराब विकल्प समय से पहले निराशा है।
रॉबर्ट हार्वे

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

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

6

यह तय करने के दो प्रमुख तरीके हैं कि क्या कोई वस्तु अपरिवर्तनीय है।

क) वस्तु की प्रकृति के आधार पर

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

बी) डिजाइन की पसंद, बाहरी कारकों के आधार पर

यह java.lang.String उदाहरण के समान है। स्ट्रिंग्स वास्तव में समय के साथ बदल सकते हैं लेकिन डिजाइन द्वारा, उन्होंने कैशिंग / स्ट्रिंग पूल / संगामिति कारकों के कारण इसे अपरिवर्तनीय बना दिया है। यदि कैशिंग / संगामिति और संबंधित प्रदर्शन अनुप्रयोग में महत्वपूर्ण है, तो सिलेरी कैशिंग / कंसीडर आदि वस्तु को अपरिवर्तनीय बनाने में अच्छी भूमिका निभा सकते हैं। लेकिन सभी प्रभावों के अनुरेखण के बाद इस निर्णय को बहुत सावधानी से लिया जाना चाहिए।

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


4

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

एक कार्यक्रम की स्थिति को कम करना अत्यधिक फायदेमंद है।

उनसे पूछें कि क्या वे क्लाइंट क्लास से अस्थायी भंडारण के लिए आपकी कक्षाओं में एक परिवर्तनशील मूल्य प्रकार का उपयोग करना चाहते हैं।

यदि वे हां कहते हैं, तो पूछें कि क्यों? इस तरह के परिदृश्य में उत्परिवर्तनीय स्थिति नहीं होती है। उन्हें उस राज्य को बनाने के लिए मजबूर करना जहां यह वास्तव में है और आपके डेटा प्रकारों की स्थिति को यथासंभव स्पष्ट बनाने के लिए उत्कृष्ट कारण हैं।


4

इसका उत्तर कुछ हद तक भाषा-निर्भर है। आपका कोड जावा की तरह दिखता है, जहां यह समस्या यथासंभव कठिन है। जावा में, वस्तुओं को केवल संदर्भ द्वारा पारित किया जा सकता है, और क्लोन पूरी तरह से टूट गया है।

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

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

बड़े मूल्य की वस्तुओं के लिए, यदि उन्हें अपरिवर्तनीय बनाने में असुविधा होती है, तो उन्हें कॉपी करना आसान बनाएं।


कैसे ढेर और ढेर के बीच चयन करने के लिए जब सी या सी ++ :) लेखन की तरह एक बहुत लग रहा है
Ricket

@ टिकट: इतना आईएमओ नहीं। स्टैक / हीप वस्तु जीवनकाल पर निर्भर करता है। स्टैक पर परस्पर वस्तुओं का होना C ++ में बहुत आम है।
केविन क्लाइन

1

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

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

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

आपके पास अमान्य राज्य में किसी ऑब्जेक्ट के निर्माण के जोखिम के बारे में एक अच्छा बिंदु है, लेकिन यह वास्तव में अपरिवर्तनीयता से एक अलग मुद्दा है। एक निर्माण के बाद एक वस्तु परस्पर और हमेशा वैध अवस्था में हो सकती है।

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


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

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

0

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

उदाहरण के लिए, यह बहुत महंगा हो सकता है:

/// @return A new mesh whose vertices have been transformed
/// by the specified transformation matrix.
Mesh transform(Mesh mesh, Matrix4f matrix);

... अगर Meshएक सतत डेटा संरचना होने के लिए डिज़ाइन नहीं किया गया है और इसके बजाय, एक डेटा प्रकार जो इसे पूर्ण में कॉपी करने की आवश्यकता है (जो कुछ परिदृश्य में गीगाबाइट्स को फैला सकता है) भले ही हम सब करने जा रहे हैं एक बदल रहा है इसका हिस्सा (जैसे ऊपर के परिदृश्य में जहां हम केवल शीर्ष पदों को संशोधित करते हैं)।

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

मेरे मामले में यह बहुत महंगा है (कम से कम एक उत्पादकता दृष्टिकोण से) सब कुछ अपरिवर्तनीय बनाने के लिए, इसलिए मैं इसे उन वर्गों के लिए बचा लेता हूं जो पूरी तरह से गहरी प्रतिलिपि के लिए बहुत महंगे हैं। वे कक्षाएं आमतौर पर जाल और छवियों जैसी भारी डेटा संरचनाएं होती हैं और मैं आम तौर पर एक नई अपरिवर्तनीय प्रतिलिपि प्राप्त करने के लिए "बिल्डर" ऑब्जेक्ट के माध्यम से उनमें परिवर्तन व्यक्त करने के लिए एक परिवर्तनशील इंटरफ़ेस का उपयोग करता हूं। और मैं ऐसा नहीं कर रहा हूँ ताकि कक्षा के केंद्रीय स्तर पर अपरिवर्तनीय गारंटी प्राप्त करने की कोशिश करूँ, ताकि मुझे उन कार्यों में कक्षा का उपयोग करने में मदद मिल सके जो दुष्प्रभाव से मुक्त हो सकते हैं। Meshऊपर से अपरिवर्तनीय बनाने की मेरी इच्छा सीधे तौर पर मेषों को अपरिवर्तनीय बनाने की नहीं है, लेकिन आसानी से लिखने के कार्यों को साइड इफेक्ट्स से मुक्त करने की अनुमति देने के लिए है जो एक जाल का आदान-प्रदान करते हैं और बदले में एक बड़ी स्मृति और कम्प्यूटेशनल लागत का भुगतान किए बिना एक नया उत्पादन करते हैं।

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

/// @return The v1 * v2.
Vector3f vec_mul(Vector3f v1, Vector3f v2);

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


-1
Foo a = new Foo();
a.setProperty1("asdf");
a.setProperty2("bcde");

यदि फू में केवल दो गुण हैं, तो एक रचनाकार लिखना आसान है जो दो तर्क लेता है। लेकिन मान लीजिए कि आप एक और संपत्ति जोड़ते हैं। फिर आपको एक और कंस्ट्रक्टर जोड़ना होगा:

public Foo(String a, String b, SomethingElse c)

इस बिंदु पर, यह अभी भी प्रबंधनीय है। लेकिन क्या होगा अगर 10 गुण हैं? आप 10 तर्कों के साथ एक निर्माता नहीं चाहते हैं। आप इंस्टेंसेस बनाने के लिए बिल्डर पैटर्न का उपयोग कर सकते हैं, लेकिन यह जटिलता जोड़ता है। इस समय तक, आप सोच रहे होंगे "मैंने सामान्य लोगों की तरह सभी गुणों के लिए बसने वाले को क्यों नहीं जोड़ा"?


4
क्या एक निर्माता दस तर्कों के साथ NullPointerException से भी बदतर है जो तब होता है जब प्रॉपर्टी 7 सेट नहीं किया गया था? क्या प्रत्येक विधि में असंवैधानिक गुणों की जांच करने के लिए कोड की तुलना में बिल्डर पैटर्न अधिक जटिल है? जब वस्तु का निर्माण हो तो एक बार जांच करना बेहतर होगा।
केविनलाइन


1
आप 10 तर्कों के साथ एक निर्माता क्यों नहीं चाहेंगे? आप किस बिंदु पर रेखा खींचते हैं? मुझे लगता है कि 10 तर्कों के साथ एक निर्माणकर्ता अपरिवर्तनीयता के लाभों के लिए भुगतान करने के लिए एक छोटी सी कीमत है। साथ ही, या तो आपके पास 10 चीजें हैं जो कॉमा से अलग हो जाती हैं (वैकल्पिक रूप से कई लाइनों या यहां तक ​​कि 10 लाइनों में फैल जाती हैं, अगर यह बेहतर दिखती है), या आपके पास 10 लाइनें वैसे भी हैं जैसे कि आप प्रत्येक संपत्ति को व्यक्तिगत रूप से सेट करते हैं ...
Ricket

1
@ टिकट: क्योंकि इससे तर्कों को गलत क्रम में रखने का जोखिम बढ़ जाता है । यदि आप बसने वाले या बिल्डर पैटर्न का उपयोग कर रहे हैं, तो इसकी संभावना बहुत कम है।
माइक बैरनज़क

4
यदि आपके पास 10 तर्कों के साथ एक रचनाकार है, तो शायद उन तर्कों को अपने स्वयं के वर्ग (या कक्षाओं) में सम्मिलित करने और / या आपकी कक्षा के डिजाइन पर एक महत्वपूर्ण नज़र डालने के बारे में सोचने का समय है।
एडम लेअर
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.