यदि एक चर में गेट्टर और सेटर है, तो क्या यह सार्वजनिक होना चाहिए?


23

मेरे पास एक वैरिएबल के साथ एक वर्ग है जो निजी है और कक्षा में एक चर और उस चर के लिए एक सेटर है। उस चर को सार्वजनिक क्यों नहीं किया जाता?

एकमात्र मामला मुझे लगता है कि आपको गेटर्स और सेटर्स का उपयोग करना होगा यदि आपको सेट या प्राप्त करने के अलावा कुछ ऑपरेशन करने की आवश्यकता है। उदाहरण:

void my_class::set_variable(int x){
   /* Some operation like updating a log */
   this->variable = x;
}

10
परिरक्षण के लिए गेटर्स और सेटर मौजूद हैं। किसी दिन आप सेटर में this->variable = x + 5एक UpdateStatisticsफ़ंक्शन करना या कॉल करना चाहते हैं , और उन मामलों में classinstancea->variable = 5समस्याएँ पैदा होंगी।
कोडर

1
एक अन्य उदाहरण है: set_inch, set_centimeter, get_inch, get_centimeter, कुछ डरावना कार्यों के साथ।
रॉव

हां, गेटर्स और सेटर आपको अपने उदाहरण को नियंत्रित करने में मदद करते हैं जिस तरह से आप उन्हें नियंत्रित करने की इच्छा रखते हैं।
developerdoug

7
@ कोडर: आप अपने गेटटर / सेटर को हमेशा जोड़ सकते हैं जब जरूरत पड़ती है? या यह कुछ ऐसा है जो आप आसानी से C ++ में नहीं कर सकते (मेरा अनुभव ज्यादातर डेल्फी है)?
मार्जन वेनेमा

यह सवाल: programmers.stackexchange.com/questions/21802/… रुचि का हो सकता है।
विंस्टन इवर्ट

जवाबों:


21

क्या आपने कभी किसी संपत्ति के बारे में सुना है?

एक संपत्ति एक क्षेत्र है जिसमें "अंतर्निहित" एक्सेसर्स (गेटर्स और सेटर) हैं। उदाहरण के लिए, जावा में गुण नहीं हैं, लेकिन यह गेटर्स लिखने और एक निजी क्षेत्र में बसने की सिफारिश की गई है। C # में गुण हैं।

तो, हमें गेटर्स और सेटर की आवश्यकता क्यों है? मूल रूप से हमें इस क्षेत्र को बचाने / ढालने की आवश्यकता है । उदाहरण के लिए, आप मेमोरी के संदर्भ में फ़ील्ड को एक्सेस नहीं कर रहे हैं, आप एक ऐसी विधि का उपयोग कर रहे हैं जो तब फ़ील्ड (संदर्भ) को बदल देगा। यह विधि कुछ ऑपरेशनों को करने में सक्षम है जो एक उपयोगकर्ता आपके उदाहरण में (जानने के लिए ) व्यवहार के लिए तैयार नहीं है । उदाहरण के लिए, कल्पना करें कि एक दर्जन कक्षाएं आपके सार्वजनिक क्षेत्र का उपयोग करती हैं और आपको इसके उपयोग के तरीके को बदलने की आवश्यकता है ... आपको फ़ील्ड का उपयोग करने के तरीके को बदलने के लिए उन कक्षाओं में से प्रत्येक को देखना होगा ... नहीं इसलिए "ओलीश"।

लेकिन, उदाहरण के लिए, यदि आपके पास बूलियन फ़ील्ड है जिसे मृत कहा जाता है। आपको एक सेटडेड और आईडेड घोषित करने से पहले दो बार सोचना चाहिए। आपको ऐसे एक्सेसर्स को लिखना चाहिए जो मानव पठनीय हैं , उदाहरण के लिए, सेटडीड के बजाय किल ()।

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


2
अब "मानव पठनीय" आखिरकार एक तर्क है जिसे मैं "टटोल सकता हूं"। अन्य सभी तर्क जो मैं आमतौर पर सुनता हूं, वे भविष्य के किसी प्रकार के प्रमाण हैं जो जरूरत पड़ने पर आसानी से संबोधित किए जाते हैं ...
मार्जन वेनेमा

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

2
आप वास्तव में एक शानदार बिंदु बढ़ाते हैं। मारना कोई सेट / प्राप्त नहीं है, यह एक कार्रवाई है। यह पूरी तरह से कार्यान्वयन को छुपाता है - यह है कि आप OO कोड कैसे बनाते हैं। गुण, दूसरी तरफ, बसने वाले / पाने वाले के रूप में बेवकूफ - बेवकूफ इसलिए भी क्योंकि आसान वाक्यविन्यास लोगों को केवल चर में जोड़ने के लिए प्रोत्साहित करता है जब उन्हें ज़रूरत नहीं होती है (ओओ-फ़र्बर होने की प्रतीक्षा में)। जब वे अपने मृत झंडे में "संपत्ति" टैग जोड़ सकते हैं, तो कौन मारने () का उपयोग करने के बारे में सोचेगा?
बिल के

1
प्रश्न को C ++ प्रश्न टैग किया जाता है। C ++ संपत्तियों का समर्थन नहीं करता है, तो आप इसे पोस्ट भी क्यों करेंगे?
थॉमस ईडिंग

1
@ThomasEding: C ++ ओवरराइड असाइनमेंट ऑपरेटरों के लिए कुछ विशिष्ट है। हालांकि C ++ "संपत्ति" शब्द का उपयोग उसी तरह से नहीं करता है, जैसे C # या VB.NET जैसी भाषाओं में, अवधारणा अभी भी है। C ++ में ऑपरेटर ओवरलोडिंग का उपयोग करना संभव है, ताकि मूल्यांकन के लिए foo.bar = biz.baz+5एक फ़ंक्शन को कॉल bizकिया जा सके baz, फिर पांच को इसमें जोड़ें और परिणामी मान पर fooसेट barकरने के लिए फ़ंक्शन को कॉल करें । ऐसे अधिभार को "गुण" नहीं कहा जाता है, लेकिन वे एक ही उद्देश्य की सेवा कर सकते हैं।
सुपरकैट

25

यह सबसे लोकप्रिय राय नहीं है, लेकिन मैं बहुत अंतर नहीं देखता हूं।

सेटर्स और गेटर्स काफी बुरे विचार हैं। मैंने इसके बारे में सोचा है और ईमानदारी से कहूं तो मैं एक सेटर / गेट्टर के बीच एक अंतर और एक संपत्ति और व्यवहार में सार्वजनिक चर के साथ नहीं आ सकता।

सिद्धांत में एक सेटर और गेट्टर या प्रॉपर्टी एक अतिरिक्त क्रिया को लेने के लिए एक स्थान जोड़ते हैं जब एक चर सेट / प्राप्त होता है और सिद्धांत रूप में वे आपके कोड को परिवर्तनों से अलग करते हैं।

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

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

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

गेटर्स के लिए - मैं अभी भी एक गेटटर और एक सार्वजनिक अंतिम चर के बीच अंतर के साथ नहीं आ सकता। यहाँ समस्या यह है कि यह किसी भी मामले में खराब OO है। आपको किसी ऑब्जेक्ट से मूल्य नहीं मांगना चाहिए और उस पर काम करना चाहिए - आपको ऑब्जेक्ट को आपके लिए एक ऑपरेशन करने के लिए कहना चाहिए।

वैसे, मैं किसी भी तरह से सार्वजनिक चर की वकालत नहीं कर रहा हूं - मैं कह रहा हूं कि बसने वाले और पाने वाले (और यहां तक ​​कि संपत्ति) भी पहले से ही सार्वजनिक चर रहे हैं।

बड़ी समस्या बस यह है कि जो लोग OO प्रोग्रामर नहीं हैं, उन्हें भी प्रॉपर्टी-बॉल्स (स्ट्रक्चर्स) में ऑब्जेक्ट बनाने के लिए सेटर और गेटर्स का इस्तेमाल करने के लिए बहुत लुभाया जाता है, जो कि पास और ऑपरेट किए जाते हैं, ऑब्जेक्ट ओरिएंटेड कोड के काम करने के तरीके से बहुत विपरीत है।


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

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

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

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

1
म्यूटेबल स्थिति स्वीकार्य है, लेकिन फिर से आपको अपनी वस्तु को आपके लिए कुछ करने के लिए कहना चाहिए, न कि अपनी वस्तु के लिए किसी तरह का काम करना चाहिए - इसलिए जब आप अपने राज्य को म्यूट करते हैं तो एक सेटर इसे करने का एक शानदार तरीका नहीं है, तर्क के साथ एक व्यवसाय विधि लिखने का प्रयास करें। इसके बजाय में। उदाहरण के लिए, सेटज़लोकेशन (गेटज़लोकेशन () + 5) के बजाय "मूव (अप 5)"।
बिल के

8

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

उदाहरण के लिए यदि 3 अन्य ऑब्जेक्ट foo.barबार का मान प्राप्त करने के लिए कॉल करते हैं और आप बार का नाम बदलने का निर्णय लेते हैं तो आपके हाथों में समस्या है। यदि foo.barआपके पास बुलाए गए ऑब्जेक्ट को उन सभी वर्गों को बदलना होगा जिनके पास यह है। यदि सेटर / गेट्टर का उपयोग किया जाता है तो आपके पास बदलने के लिए कुछ भी नहीं है। एक अन्य संभावना परिवर्तनशील के प्रकार को बदल रही है जिस स्थिति में बस गेट्टर / सेटर में कुछ परिवर्तन कोड जोड़ें और आप ठीक हैं।


1
+1 - सदस्य चर कार्यान्वयन कर रहा है, गेट्टर और सेटर इंटरफ़ेस हैं। केवल इंटरफ़ेस सार्वजनिक होना चाहिए। इसके अलावा, गेट्टर और सेटर के नामों को एक अमूर्तता के संदर्भ में समझ में आना चाहिए, चाहे वह कोई साधारण सदस्य चर हो जो उन्हें अंतर्निहित है या कोई अन्य कार्यान्वयन है। वहाँ रहे हैं अपवाद - ऐसे मामलों में जहां एक उपतंत्र कसकर युग्मित वर्गों से बनाया सबसे आसान तरीका है - लेकिन यह है कि अभी भी एक स्तर ऊपर डेटा-छुपा सीमा धक्का, वर्ग है कि पूरे सबसिस्टम का प्रतिनिधित्व करता है।
स्टीव ३१४

क्या मुझे क्लास के अंदर काम को बदलने की जरूरत नहीं है? यह ऐसा कुछ है जो डेल्फी में आसानी से किया जाता है, लेकिन शायद अन्य भाषाओं में नहीं?
मार्जन वेनेमा

@ मार्जन ज़रूर, आप बाद में किसी भी बिंदु पर गेट्टर / सेटर का परिचय दे सकते हैं। इसके बाद मुद्दा यह है कि आपको वापस जाना होगा और सभी कोड को बदलना होगा जो कि सार्वजनिक क्षेत्र का उपयोग गटर / सेटर के बजाय कर रहा था। मुझे यकीन नहीं है कि अगर मैं उलझन में हूं या आप हैं। 0.o
पीट

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

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

5

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

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


आपका बहुत बहुत धन्यवाद! मैं वही मामला सोच रहा था जिसका आप उल्लेख करते हैं। अगर मुझे एक वेरिएंट में सामग्री चाहिए [0,1] तो मुझे इसके सेटर में आने वाले मूल्य की जांच करनी चाहिए :)
Oni

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

यदि आप C # का उपयोग कर रहे हैं, तो संपत्तियों का उपयोग करें, यदि आप किसी निजी उदाहरण को सेट करने के लिए किसी संपत्ति का उपयोग कर सकते हैं, तो संपत्ति के सेटर भाग में कुछ तर्क के आधार पर आवश्यक है।
developerdoug

2

आप कहते हैं "मुझे लगता है कि आपको गेटर्स और सेटर का उपयोग करने का एकमात्र मामला है, अगर आपको सेट या गेट के अलावा कुछ ऑपरेशन करने की आवश्यकता है।"

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

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


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

1

सबसे पहले आपको प्रतिमान पर स्पष्ट होना चाहिए।

  • डेटा स्ट्रक्चर्स -> मेमोरी का एक लेआउट जिसे उपयुक्त जानकार कार्यों द्वारा ट्रेस और हेरफेर किया जा सकता है।
  • ऑब्जेक्ट्स -> एक स्व-निहित मॉड्यूल जो इसके कार्यान्वयन को छुपाता है और एक इंटरफ़ेस प्रदान करता है जिसके माध्यम से संचार किया जा सकता है।

गेट्टर / सेटर कहां उपयोगी है?

क्या डेटा संरचना में गेटर्स / सेटर्स उपयोगी हैं? नहीं।

डेटा संरचना एक मेमोरी लेआउट विनिर्देश है जो फ़ंक्शन के परिवार द्वारा आम है और हेरफेर किया गया है।

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

मुझे गलत मत समझिए कि हर जगह टांके, टर्न-कोट्स और डबल-एजेंट्स के साथ उस डेटा-स्ट्रक्चर पर वार करने वाले फंक्शन्स के कई परिवार हो सकते हैं। यह ठीक है जब वे प्रत्येक के साथ खेलने के लिए अपनी स्वयं की डेटा-संरचना है, लेकिन जब वे इसे साझा करते हैं ... बस राजनीति पर असहमत कई अपराध परिवारों की कल्पना करें, यह वास्तव में तेजी से गड़बड़ हो सकता है।

यह देखते हुए कि गड़बड़ विस्तारित फंक्शन परिवारों को प्राप्त हो सकता है, क्या डेटा संरचना को एन्कोड करने का एक तरीका है ताकि दुष्ट फ़ंक्शन सब कुछ गड़बड़ न करें? हां, उन्हें ऑब्जेक्ट कहा जाता है।

क्या ऑब्जेक्ट में गेटर्स / सेटर उपयोगी हैं? नहीं।

एक वस्तु में एक डेटा संरचना को लपेटने का पूरा बिंदु यह सुनिश्चित करना था कि कोई दुष्ट कार्य मौजूद न हो। यदि फ़ंक्शन परिवार में शामिल होना चाहता था, तो उसे पहले अच्छी तरह से वीटो करना पड़ा और फिर ऑब्जेक्ट का हिस्सा बन गया।

एक गेट्टर और एक सेटर का बिंदु / उद्देश्य सीधे ऑब्जेक्ट के मेमोरी लेआउट को बदलने के लिए ऑब्जेक्ट के बाहर फ़ंक्शन करने की अनुमति देता है। कि बदमाशों को अनुमति देने के लिए एक खुले दरवाजे की तरह लगता है ...

द एज केस

वहाँ दो स्थितियों में एक सार्वजनिक पानेवाला / सेटर मेक सेंस थे।

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

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

दुर्भाग्य से कई कार्यान्वयन इस गलत हो जाते हैं और वास्तविक वस्तु तक सीधे पहुंच देने के लिए इस प्रकार की वस्तुओं के इंटरफेस को परिभाषित करते हैं। कुछ इस तरह:

interface Container<T>
{
    typedef ...T... TRef; //<somehow make TRef to be a reference or pointer to the memory location of T
    TRef item(int index); 
}

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

आप केवल कॉपी-शब्दार्थ का उपयोग करके, या प्रॉक्सी का उपयोग करके गेटर्स / सेटर को सुधार / सुधार सकते हैं:

interface Proxy<T>
{
     operator T(); //<returns a copy
     ... operator ->(); //<permits a function call to be forwarded to an element
     Proxy<T> operator=(T); //< permits the specific element to be replaced/assigned by another T.
}

interface Container<T>
{
     Proxy<T> item(int index);
     T item(int index); //<When T is a copy of the original value.
     void item(int index, T new_value); //<where new_value is used to replace the old value
}

संभवतः एक दुष्ट फ़ंक्शन अभी भी यहां तबाही खेल सकता है (पर्याप्त प्रयास के साथ अधिकांश चीजें संभव हैं), लेकिन कॉपी-शब्दार्थ और / या प्रॉक्सी कई त्रुटियों के लिए मौका कम कर देता है।

  • बाढ़
  • अधःप्रवाह
  • उप तत्व के साथ बातचीत टाइप-चेक / टाइप-चेक करने योग्य होती है (प्रकार भाषा में खो जाना यह एक वरदान है)
  • वास्तविक तत्व स्मृति निवासी हो सकता है या नहीं भी हो सकता है।

निजी गेटर्स / सेटर्स

यह गेटर्स का अंतिम गढ़ है और सीधे प्रकार पर काम कर रहा है। वास्तव में मैं इन गेटर्स और सेटर्स को एक्सेस नहीं करूंगा लेकिन एक्सेसर्स और मैनिपुलेटर्स।

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

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

संरक्षित गेट / सेटर्स

एक संरक्षित संदर्भ में, यह सार्वजनिक संदर्भ के लिए बहुत भिन्न नहीं है। विदेशी संभवतः दुष्ट कार्य डेटा-संरचना तक पहुंच चाहते हैं। इसलिए नहीं, यदि वे मौजूद हैं तो वे सार्वजनिक गेटर्स / सेटर की तरह काम करते हैं।


0

C ++ अनुभव से, सेटर / गेट्टर 2 परिदृश्यों के लिए सहायक है:

  1. यदि आपको सदस्य को स्ट्रिंग्स या सरणी जैसे मान असाइन करने से पहले पवित्रता जांचना है।
  2. यह तब सहायक हो सकता है जब -1 (या नकारात्मक मान) गलत होने पर फ़ंक्शन ओवरलोडिंग को इंट वैल्यू की तरह आवश्यक हो। और इसके ठीक बाद पाने वाले के लिए।

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

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.