आप किसी ऑब्जेक्ट विधि से ऑब्जेक्ट प्रॉपर्टी तक कैसे पहुंचेंगे? [बन्द है]


96

ऑब्जेक्ट के गुणों को किसी ऑब्जेक्ट विधि से प्राप्त करने के लिए "शुद्धतावादी" या "सही" तरीका क्या है जो कि एक गेट्टर / सेटर विधि नहीं है?

मुझे पता है कि ऑब्जेक्ट के बाहर से आपको एक गेटटर / सेटर का उपयोग करना चाहिए, लेकिन भीतर से आप बस करेंगे:

जावा:

String property = this.property;

पीएचपी:

$property = $this->property;

या आप करेंगे:

जावा:

String property = this.getProperty();

पीएचपी:

$property = $this->getProperty();

मुझे माफ कर दो अगर मेरा जावा थोड़ा बंद है, तो मुझे जावा में प्रोग्राम किए एक साल हो गया है ...

संपादित करें:

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

जवाबों:


62

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


संपत्ति के मूल्य को जावा में गलत उपयोग का एक उदाहरण सेट करने के अलावा एक सेटर में कुछ और नहीं कर रहा है।
euphoria83

1
@ व्यंजना शायद, लेकिन ऐसा होने से रोकता नहीं है।
ग्रेग हर्लमैन

मैं मूल उत्तर से सहमत हूं। हालाँकि, बस यह याद रखें कि यदि आप कक्षा या ऑब्जेक्ट के अंदर कुछ निजी सेटिंग कर रहे हैं या कर रहे हैं, तो आपको यह सुनिश्चित करने की आवश्यकता है कि गेट्टर / सेटर किसी तरह से चक्रीय या निरर्थक नहीं है, जिससे आपका कोड विफल हो जाता है। यदि आप गेटटर / सेटर का उपयोग नहीं कर सकते हैं, तो इसे सीधे एक्सेस करें। (पूर्व। आपका गेट्टर / सेटर डेटा में हेरफेर करने के लिए एक माध्यमिक (निजी / संरक्षित) विधि का उपयोग करता है।)
रिक मैक गिलिस

43

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

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


26

मुझे इस बात पर काफी हैरानी है कि यह भावना एकमत कैसे है gettersऔर बसने वाले ठीक और अच्छे हैं। मैं एलन होलब " गेटर्स एंड सेटर्स एविल " द्वारा आग लगानेवाला लेख का सुझाव देता हूं । दी, शीर्षक सदमे मूल्य के लिए है, लेकिन लेखक मान्य अंक बनाता है।

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

इसके अलावा, ओओ के कड़ाई से देखने से, वस्तुओं को उन संदेशों (तरीकों) पर प्रतिक्रिया देनी चाहिए जो उनके (उम्मीद) एकल जिम्मेदारी के अनुरूप हैं। का विशाल बहुमत gettersऔर settersउनके घटक वस्तुओं के लिए कोई मतलब नहीं है; Pen.dispenseInkOnto(Surface)मुझसे अधिक समझ में आता है Pen.getColor()

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

हालाँकि, गेटर्स और सेटर, परतों की सीमा पर आवश्यक बुराइयाँ हैं - UI, दृढ़ता और आगे। किसी कक्षा के इंटर्न के लिए प्रतिबंधित पहुँच, जैसे कि C ++ का मित्र कीवर्ड, जावा का पैकेज संरक्षित एक्सेस, .NET का आंतरिक एक्सेस और मित्र वर्ग पैटर्न आपको gettersउन लोगों की दृश्यता को कम करने में मदद कर सकता है, जो केवल उन्हीं की आवश्यकता के लिए बसते हैं।


19

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

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


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

क्या होगा अगर आप कुछ प्रकार के बूलियन को गटर में जोड़ते हैं जैसे: PHP: सार्वजनिक फ़ंक्शन getName ($ outCall = true) {if ($ outCall) {$ this-> incrementNameCalled (); } $ यह लौटें-> नाम; } और फिर ऑब्जेक्ट के भीतर से, यदि आपको नाम मिलता है, तो आप इसे बढ़ाकर: PHP: $ नाम = $ इस-> getName (गलत) से रख सकते हैं; क्या मैं अभी यहाँ पर जा रहा हूँ?
cmcculloh

14

PHP मैजिक मेथड्स सहित, इसे हैंडल करने के तरीकों का एक असंख्य प्रदान करता है __getऔर __set, लेकिन मुझे स्पष्ट गेटर्स और सेटर्स पसंद हैं। यहाँ पर क्यों:

  1. सत्यापन को बसने वालों में रखा जा सकता है (और उस मामले के लिए गेटर्स)
  2. Intellisense स्पष्ट तरीकों के साथ काम करता है
  3. कोई सवाल नहीं कि क्या एक संपत्ति केवल पढ़ी जाती है, केवल लिखना या पढ़ना-लिखना
  4. वर्चुअल प्रॉपर्टी (यानी परिकलित मान) को पुनः प्राप्त करना नियमित गुणों के समान दिखता है
  5. आप आसानी से एक वस्तु संपत्ति सेट कर सकते हैं जो वास्तव में कभी भी कहीं भी परिभाषित नहीं होती है, जो तब अनिर्दिष्ट हो जाती है

13

क्या मैं अभी यहाँ पर जा रहा हूँ?

शायद)

एक अन्य तरीका यह होगा कि निजी / संरक्षित विधि का उपयोग वास्तव में (कैशिंग / डीबी / इत्यादि) करने के लिए किया जाए, और इसके लिए एक सार्वजनिक आवरण जो कि गिनती बढ़ाता है:

पीएचपी:

public function getName() {
    $this->incrementNameCalled();
    return $this->_getName();
}

protected function _getName() {
    return $this->name;
}

और फिर वस्तु के भीतर से ही:

पीएचपी:

$name = $this->_getName();

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


12

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

इसे अपने निष्कर्ष पर ले जाने वाले को एक गेटवे को कॉल करना चाहिए, जिसे गेटर को कॉल करना चाहिए।

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


मुझे उसी जरूरत से प्रेरित किया गया था जिसमें आपको टिप्पणी करनी थी ... इसके अलावा इसका उत्तर बंद नहीं किया गया था;)
एग वैन

8

प्योरिस्ट ओओ तरीका दोनों से बचना है और टेल ऑफ डॉक पूछो दृष्टिकोण का उपयोग करके कानून के कानून का पालन ​​करना है ।

ऑब्जेक्ट की संपत्ति का मूल्य प्राप्त करने के बजाय, जो दो वर्गों को कसकर जोड़े , ऑब्जेक्ट को पैरामीटर के रूप में उपयोग करते हैं जैसे

  doSomethingWithProperty() {
     doSomethingWith( this.property ) ;
  }

जहां संपत्ति एक मूल प्रकार थी, उदाहरण के लिए, एक पहुंच विधि का उपयोग करें, इसे समस्या डोमेन के लिए नाम दें, प्रोग्रामिंग डोमेन नहीं।

  doSomethingWithProperty( this.daysPerWeek() ) ;

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


8

ऑब्जेक्ट के भीतर भी एक्सेसर के तरीकों का उपयोग करना बेहतर है। यहाँ मेरे दिमाग में तुरंत आने वाले बिंदु हैं:

  1. यह वस्तु के बाहर से पहुंच के साथ स्थिरता बनाए रखने के हित में किया जाना चाहिए।

  2. कुछ मामलों में, ये एक्सेसर विधियाँ केवल क्षेत्र तक पहुँचने से अधिक कर सकती हैं; वे कुछ अतिरिक्त प्रसंस्करण कर सकते हैं (हालांकि यह दुर्लभ है)। यदि यह मामला है, तो सीधे क्षेत्र तक पहुँचने का मतलब यह होगा कि आप उस अतिरिक्त प्रसंस्करण को याद कर रहे हैं, और आपका प्रोग्राम तब जा सकता है जब यह प्रसंस्करण उन पहुँच के दौरान हमेशा किया जाना है।


8

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


7

मैं बसने / पाने वालों का उपयोग कर पाया है, मेरे कोड को पढ़ना आसान बना दिया है। मुझे यह भी पसंद है कि यह नियंत्रण तब देता है जब अन्य वर्ग विधियों का उपयोग करते हैं और यदि मैं डेटा को परिवर्तित करता हूं तो संपत्ति संग्रहीत होगी।


7

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

.NET डेवलपर्स इसे लागू करने के लिए स्वचालित गुणों का उपयोग कर सकते हैं क्योंकि आप डिज़ाइन समय पर बैकिंग चर भी नहीं देख सकते हैं।



7

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


7

यदि मैं संपत्ति को संपादित नहीं करता हूं, तो मैं एक सार्वजनिक पद्धति का उपयोग करूंगा get_property()जब तक कि यह एक विशेष अवसर जैसे कि किसी अन्य वस्तु के अंदर MySQLi ऑब्जेक्ट नहीं है, जिस स्थिति में मैं संपत्ति को सार्वजनिक करूंगा और इसे संदर्भित करूंगा $obj->object_property

वस्तु के अंदर यह हमेशा $ है- मेरे लिए संपत्ति।


5

ठीक है, यह C # 3.0 गुणों के डिफ़ॉल्ट कार्यान्वयन के साथ लगता है, निर्णय आपके लिए लिया गया है; आप (संभवतः निजी) संपत्ति सेटर का उपयोग कर संपत्ति सेट करने के लिए है।

मैं व्यक्तिगत रूप से केवल निजी सदस्य के पीछे का उपयोग करता हूं, ऐसा नहीं करने पर वस्तु वांछनीय स्थिति से कम में गिर जाएगी, जैसे कि जब इनिशियलाइज़िंग या कैज़िंग / आलसी लोडिंग शामिल होती है।


5

मुझे cmcculloh द्वारा उत्तर पसंद है , लेकिन ऐसा लगता है कि सबसे सही एक ग्रेग हर्लमैन द्वारा उत्तर है । यदि आप उन्हें गेट-गो से उपयोग करना शुरू करते हैं और / या आप उनके साथ काम करने के आदी हैं, तो हर समय गेटटर / सेटर का उपयोग करें।

एक तरफ के रूप में, मुझे व्यक्तिगत रूप से पता चलता है कि गेटटर / सेटर का उपयोग करके कोड को पढ़ना और बाद में डिबग करना आसान हो जाता है।


4

जैसा कि कुछ टिप्पणियों में कहा गया है: कभी-कभी आपको, कभी-कभी आपको नहीं करना चाहिए। निजी चर के बारे में महान हिस्सा यह है कि आप उन सभी स्थानों को देखने में सक्षम होते हैं जिनका उपयोग आप कुछ बदलने के दौरान करते हैं। यदि आपका गेटटर / सेटर आपकी ज़रूरत का कुछ करता है, तो उसका उपयोग करें। अगर इससे कोई फर्क नहीं पड़ता कि आप तय करते हैं।

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

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