OOP में दस्तावेज़ीकरण यह निर्दिष्ट करने से बचना चाहिए कि "गेट्टर" कोई संगणना करता है या नहीं?


39

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

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

उदाहरण के लिए, यदि किसी वर्ग Personमें विशेषता है age, तो वह दावा करता है कि यह बताना असंभव है, कि संकेतन से, चाहे वह Person.ageआंतरिक रूप से किसी चीज से मेल खाता हो, return current_year - self.birth_dateया return self.ageजहां self.ageउसे एक स्थिर विशेषता के रूप में परिभाषित किया गया हो। मुझे यह अर्थपूर्ण लग रहा है। हालाँकि, वह निम्नलिखित का दावा करता है:

एक वर्ग के लिए मानक ग्राहक प्रलेखन, जिसे कक्षा के संक्षिप्त रूप के रूप में जाना जाता है, को तैयार किया जाएगा ताकि यह प्रकट न हो सके कि दी गई विशेषता एक विशेषता है या एक फ़ंक्शन (उन मामलों में जिसके लिए यह या तो हो सकता है)।

यानी, वह दावा करता है कि वर्ग के लिए प्रलेखन को यह निर्दिष्ट करने से भी बचना चाहिए कि "गेट्टर" कोई गणना करता है या नहीं।

यह, मैं अनुसरण नहीं करता। क्या दस्तावेज़ीकरण एक जगह नहीं है जहां इस अंतर के उपयोगकर्ताओं को सूचित करना महत्वपूर्ण होगा? अगर मैं Personवस्तुओं से भरा एक डेटाबेस डिजाइन करने के लिए था , तो क्या यह जानना महत्वपूर्ण नहीं होगा कि Person.ageएक महंगी कॉल है या नहीं , इसलिए मैं यह तय कर सकता हूं कि क्या इसके लिए कुछ प्रकार के कैश को लागू करना है या नहीं? क्या मैंने गलत समझा है कि वह क्या कह रहा है, या वह ओओपी डिजाइन दर्शन का सिर्फ एक विशेष रूप से चरम उदाहरण है?


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

मैंने किताब नहीं पढ़ी है। क्या मेयर प्रलेखन की शैली का कोई उदाहरण देता है जिसे वह सुझाता है? मुझे यह कल्पना करना मुश्किल है कि आपने किसी भी भाषा के लिए काम करने का क्या वर्णन किया है ।
user16764

1
@PatrickCollins मेरा सुझाव है कि आप 'संज्ञा के राज्य में निष्पादन' पढ़ें और यहाँ क्रिया और संज्ञा की अवधारणा के पीछे जाएँ। दूसरे OOP
गेटर्स

@AndreasScheinert - आप की बात कर रहे इस ? मैं "एक घोड़े की नाल की चाह के लिए सभी" पर चकित था, लेकिन यह वस्तु उन्मुख प्रोग्रामिंग की बुराइयों के बारे में एक शेख़ी लगता है।
पैट्रिक कॉलिन्स

1
@PatrickCollins हाँ यह: steve-yegge.blogspot.com/2006/03/… ! यह कुछ बिंदुओं को इंगित करता है, अन्य हैं: आपको बसर का उपयोग करके अपनी वस्तुओं को डेटा संरचनाओं में बदलना चाहिए।
एंड्रियाशेचेर्ट

जवाबों:


58

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

लेकिन आपकी कक्षा का उपयोग करने वाले कोडर को यह जानने की आवश्यकता नहीं है कि आपने क्या लागू किया है:

return currentAge;

या:

return getCurrentYear() - yearBorn;

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

लेकिन यह हमेशा ऐसा नहीं होता है, उदाहरण के लिए, मान लें कि आपके पास एक कंटेनर पर एक आकार विधि है। इसे लागू किया जा सकता है:

return size;

या

return end_pointer - start_pointer;

या यह हो सकता है:

count = 0
for(Node * node = firstNode; node; node = node->next)
{
    count++
}
return count

पहले दो के बीच का अंतर वास्तव में मायने नहीं रखता। लेकिन आखिरी में गंभीर प्रदर्शन में गड़बड़ी हो सकती है। इसलिए, उदाहरण के लिए, एसटीएल कहता .size()है O(1)। यह वास्तव में दस्तावेज नहीं करता है कि आकार की गणना कैसे की जाती है, लेकिन यह मुझे प्रदर्शन विशेषताओं को देता है।

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


4
इसके अलावा: पहले दस्तावेज़ समय / अंतरिक्ष जटिलता, फिर एक स्पष्टीकरण दें कि किसी फ़ंक्शन में वे गुण क्यों हैं। जैसे:// O(n) Traverses the entire user list.
जॉन पुरडी

2
= (पायथन के रूप में तुच्छ के रूप में कुछ lenऐसा करने में विफल रहता है ... (में कम से कम कुछ स्थितियों में, यह है O(n), जब मैं लंबाई के भंडारण के बजाय इसे हर पाश यात्रा recalculating) ने सुझाव दिया, जैसा कि हम कॉलेज में एक परियोजना में सीखा
Izkata

@ इज़कट, जिज्ञासु। क्या आपको याद है कि संरचना क्या थी O(n)?
विंस्टन एवर्ट

@WinstonEwert दुर्भाग्य से नहीं। यह एक डाटा माइनिंग प्रोजेक्ट में 4+ साल पहले था, और मैंने इसे केवल अपने दोस्त को एक कूबड़ पर सुझाया था, क्योंकि मैं सी के साथ दूसरी कक्षा में काम कर रहा था ..
इज़्काता

1
@JonPurdy मैं इसे सामान्य व्यावसायिक कोड में जोड़ना चाहूंगा, यह शायद बड़े-ओ जटिलता को निर्दिष्ट करने के लिए समझ में नहीं आता है। उदाहरण के लिए, O (n) इन-मेमोरी सूची ट्रैवर्सल की तुलना में O (1) डेटाबेस एक्सेस बहुत अधिक धीमा होने की संभावना है, इसलिए दस्तावेज़ क्या मायने रखता है। लेकिन निश्चित रूप से ऐसे मामले हैं जहां दस्तावेज जटिलता बहुत महत्वपूर्ण है (संग्रह या अन्य एल्गोरिदम-भारी कोड)।
20

16

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

हालांकि, अधिकांश वास्तविक दुनिया के कार्यक्रम जोएल स्पोल्स्की के " लॉकी अमूर्त के कानून" से पीड़ित हैं, जो कहता है

"सभी गैर-तुच्छ सार, कुछ हद तक टपका हुआ है।"

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

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


+1, प्लस अधिकांश दस्तावेज़ जो बन जाता है वह अगले प्रोग्रामर के लिए है कि वह आपकी परियोजना को बनाए रखे , न कि इसका उपयोग करने वाला अगला प्रोग्रामर ।
जोर्मेनो सेप

12

आप लिख सकते हैं कि दी गई कॉल महंगी है या नहीं। बेहतर है, जैसे एक नामकरण परंपरा का उपयोग getAgeत्वरित पहुँच और के लिए loadAgeया fetchAgeमहंगा देखने के लिए। आप निश्चित रूप से उपयोगकर्ता को सूचित करना चाहते हैं यदि विधि किसी भी IO का प्रदर्शन कर रही है।

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


1
+1 यह उल्लेख करने के लिए कि प्रलेखन एक वर्ग के अनुबंध का उतना ही हिस्सा है जितना कि इसका इंटरफ़ेस।
बार्ट वैन इनगेन शेनौ

मैं इसका समर्थन करता हूं। इसके अलावा सामान्य तौर पर व्यवहार के साथ तरीके प्रदान करके गेटर्स की आवश्यकता को कम करने की कोशिश की जाती है।
सातवें सेप

9

अगर मैं व्यक्तिगत वस्तुओं से भरा एक डेटाबेस डिजाइन करने के लिए था, तो क्या यह जानना महत्वपूर्ण नहीं होगा कि पर्सन एक महंगी कॉल है या नहीं?

हाँ।

यही कारण है कि मैं कभी-कभी Find()फ़ंक्शन का उपयोग यह इंगित करने के लिए करता हूं कि इसे कॉल करने में थोड़ी देर लग सकती है। यह किसी भी चीज की तुलना में एक सम्मेलन का अधिक है। हालांकि प्रोग्रामर के बीच वहाँ बार यह एक समारोह या वापसी के लिए विशेषता के लिए ले जाता है, कार्यक्रम के लिए कोई फर्क नहीं (हालांकि यह उपयोगकर्ता के लिए हो सकता है) बनाता है एक उम्मीद है कि, अगर यह एक विशेषता के रूप में घोषित किया जाता है, लागत इसे कहते हैं होना चाहिए कम।

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


4
+1: यह सम्मेलन काफी जगहों पर मुहावरेदार है। इसके अलावा, प्रलेखन को इंटरफ़ेस स्तर पर किया जाना चाहिए - उस बिंदु पर आप नहीं जानते कि पर्सनएज कैसे लागू किया जाता है।
15

@ टेलस्टाइन: मैंने कभी इस तरह से प्रलेखन के बारे में नहीं सोचा था; यह है, कि यह इंटरफ़ेस के स्तर पर किया जाना चाहिए। यह अब स्पष्ट लगता है। उस बहुमूल्य टिप्पणी के लिए +1।
स्टैकएक्स

मुझे यह जवाब बहुत पसंद है। इस बात का एक सटीक उदाहरण कि आप क्या वर्णन करते हैं कि प्रदर्शन कार्यक्रम के लिए एक चिंता का विषय नहीं है यदि व्यक्ति एक प्रतिष्ठित सेवा से प्राप्त एक इकाई था। GET निहित है लेकिन यह स्पष्ट नहीं है कि यह सस्ता या महंगा होगा। यह निश्चित रूप से OOP नहीं है, लेकिन बिंदु समान है।
maple_shaft

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

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

3

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

C ++ और Java जैसी भाषा में, आपको एक विशेषता और एक विधि कॉल तक पहुंचने के बीच अंतर करना चाहिए। के बीच instance.getter_methodऔर अंतर की दुनिया है instance.getter_method()। एक वास्तव में आपका मूल्य प्राप्त करता है और दूसरा नहीं करता है।

स्मालटाक या रूबी अनुनय की अधिक विशुद्ध रूप से OO भाषा के साथ काम करते समय (जो यह प्रतीत होता है कि इस पुस्तक में प्रयुक्त एफिल भाषा है), यह पूरी तरह से मान्य सलाह बन जाती है। ये भाषाएं आपके लिए निहित तरीके से कॉल करेंगी। वहाँ instance.attributeऔर के बीच कोई अंतर नहीं बनता है instance.getter_method

मैं इस बिंदु पर पसीना नहीं आता या इसे हठधर्मी रूप से लेता। इरादा अच्छा है - आप अपने वर्ग के उपयोगकर्ताओं को अप्रासंगिक कार्यान्वयन विवरणों के बारे में चिंता नहीं करना चाहते हैं - लेकिन यह कई आधुनिक भाषाओं के वाक्यविन्यास में सफाई से अनुवाद नहीं करता है।


1
उस वर्ष पर विचार करने के बारे में बहुत महत्वपूर्ण बिंदु जिसमें सुझाव दिया गया था। नित: स्मालटाक और सिमूला 60 और 70 के दशक की है, इसलिए 88 शायद ही "शुरुआती दिन" हैं।
लूजर ने

2

एक उपयोगकर्ता के रूप में, आपको यह जानने की आवश्यकता नहीं है कि कुछ कैसे कार्यान्वित किया जाता है।

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


3
क्या यह हमेशा मामला है कि एक कम्प्यूटेशनल-महंगी विधि एक बग है, हालांकि? एक तुच्छ उदाहरण के रूप में, मान लीजिए कि मैं तार की एक सरणी की लंबाई के साथ संबंध रखता हूं। आंतरिक रूप से, मुझे नहीं पता कि मेरी भाषा में तार पास्कल-शैली या सी-शैली हैं। पूर्व मामले में, चूंकि स्ट्रिंग्स उनकी लंबाई को "जानते" हैं, इसलिए मैं अपनी लंबाई-समरूप-लूप की उम्मीद कर सकता हूं ताकि तार की संख्या पर निर्भर रैखिक समय ले सकें। मुझे यह भी पता होना चाहिए कि स्ट्रिंग्स की लंबाई बदलने वाले ऑपरेशनों में उनके साथ जुड़ा हुआ एक ओवरहेड string.lengthहोगा , क्योंकि हर बार परिवर्तनों के बाद पुनर्गणना होगी।
पैट्रिक कॉलिन्स

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

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

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

2
@PatrickCollins OO प्रतिक्रिया इंटरफेस पर निर्भर है जो कार्यान्वयन नहीं है। एक इंटरफ़ेस का उपयोग न करें जो इंटरफ़ेस की परिभाषा के भाग के रूप में प्रदर्शन की गारंटी को शामिल नहीं करता है (उदाहरण के लिए C ++ 11 List.size की गारंटी ओ (1))। इसे इंटरफ़ेस की परिभाषा में कार्यान्वयन विवरणों की आवश्यकता नहीं है। यदि आपका कोड आपकी तुलना में धीमा है, तो क्या आपके पास इसके अलावा कोई अन्य उत्तर है, इसे तेजी से बदलने के लिए (बाधाओं को निर्धारित करने के लिए इसे प्रोफाइल करने के बाद) बदलना होगा?
स्टोनमेटल

2

किसी भी प्रोग्रामर-ओरिएंटेड डॉक्यूमेंटेशन जो रुटीन / विधियों की जटिलता लागत के बारे में प्रोग्रामर्स को सूचित करने में विफल रहता है, त्रुटिपूर्ण है।

  • हम साइड-इफेक्ट-फ्री तरीकों का उत्पादन करना चाहते हैं।

  • यदि किसी विधि के निष्पादन में स्मृति और या समय-विवश वातावरणों के अलावा अन्य समय जटिलता और / या स्मृति जटिलता चलती है O(1), तो इसका दुष्प्रभाव माना जा सकता है

  • कम से कम आश्चर्य की बात है के सिद्धांत इस मामले में, स्मृति का अकेले या CPU समय बर्बाद कर - अगर एक विधि कुछ पूरी तरह से अप्रत्याशित करता है का उल्लंघन किया है।


1

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

इसे संभालने का एक और तरीका हो सकता है कि आप एक नई विशेषता प्रस्तुत करें जिसका नाम यह बताता है कि एक लंबी गणना हो सकती है (जैसे कि Person.ageCalculatedFromDB) और फिर Person.ageएक मान लौटाया जाए जो कक्षा के भीतर कैश किया गया हो, लेकिन यह हमेशा उचित नहीं हो सकता है, और यह ओवरक्लम्प्लीकेट हो सकता है चीजें, मेरी राय में।


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

1
@ ब्लरफ्ल: ठीक है, कैशिंग कोPerson कक्षा में किया जाना चाहिए , लेकिन मुझे लगता है कि प्रश्न का उद्देश्य अधिक सामान्य Person.ageथा और यह केवल एक उदाहरण था। संभवत: कुछ ऐसे मामले हैं, जहां कॉल करने वाले को चुनने के लिए यह अधिक समझ में आता है - शायद कैली के पास एक ही मूल्य की गणना करने के लिए दो अलग-अलग एल्गोरिदम हैं: एक तेज लेकिन गलत, एक बहुत धीमी लेकिन अधिक सटीक (3 डी रेंडरिंग) एक जगह पर ध्यान में आती है। जहां ऐसा हो सकता है), और प्रलेखन को इसका उल्लेख करना चाहिए।
FrustratedWithFormsDesigner

जब आप हर बार एक ही उत्तर की अपेक्षा करते हैं, तो दो तरीके जो अलग-अलग परिणाम प्रदान करते हैं, एक अलग उपयोग मामला है।
Blrfl

0

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

यदि संपत्तियों का एक सटीक संबंध नहीं है (जैसे वे क्योंकि floatया doubleइसके बजाय int) हैं, तो यह आवश्यक हो सकता है कि किसी वर्ग के मूल्य को "गुण" को परिभाषित करने वाले दस्तावेज के लिए आवश्यक हो। उदाहरण के लिए, भले ही Leftप्लस Widthको बराबर माना जाता है Right, फ़्लोटिंग-पॉइंट गणित अक्सर अक्षम होता है। उदाहरण के लिए, एक लगता है Rectangleजो प्रकार का उपयोग करता Floatस्वीकार करता है Leftऔर Widthनिर्माता पैरामीटर के रूप में के साथ निर्माण किया है Leftके रूप में दिया 1234567fऔर Widthके रूप में 1.1ffloatयोग का सबसे अच्छा प्रतिनिधित्व 1234568.125 है [जो 1234568.13 के रूप में प्रदर्शित हो सकता है]; अगला छोटा float1234568.0 होगा। यदि वर्ग वास्तव में संग्रहीत करता है LeftऔरWidth, यह चौड़ाई मान की रिपोर्ट कर सकता है क्योंकि यह निर्दिष्ट किया गया था। अगर, हालांकि, निर्माता अभिकलन Rightपर पारित कर दिया-में आधारित Leftऔर Width, और बाद में अभिकलन Widthपर आधारित Leftऔर Right, यह के रूप में चौड़ाई रिपोर्ट करेंगे 1.25fबजाय के रूप में पारित-इन 1.1f

उत्परिवर्तनीय कक्षाओं के साथ, चीजें और भी दिलचस्प हो सकती हैं, चूंकि अंतर-संबंधित मूल्यों में से एक में बदलाव से कम से कम एक दूसरे के लिए एक परिवर्तन होगा, लेकिन यह हमेशा स्पष्ट नहीं हो सकता है कि कौन सा है। कुछ मामलों में, यह तरीकों जो "सेट" इस तरह के रूप में एक संपत्ति रखना ही बेहतर हो सकता है, लेकिन इसके बजाय या तो जैसे तरीके है SetLeftAndWidthया SetLeftAndRight(जैसे, वरना यह स्पष्ट करना गुण क्या निर्दिष्ट किए जा रहे हैं और जो बदल रहे हैं MoveRightEdgeToSetWidth, ChangeWidthToSetLeftEdgeया MoveShapeToSetRightEdge) ।

कभी-कभी यह एक वर्ग के लिए उपयोगी हो सकता है जो इस बात पर नज़र रखता है कि किन गुणों के मूल्यों को निर्दिष्ट किया गया है और जिन्हें दूसरों से गणना की गई है। उदाहरण के लिए, "समय में पल" वर्ग में एक निरपेक्ष समय, एक स्थानीय समय और एक समय क्षेत्र ऑफसेट शामिल हो सकते हैं। ऐसे कई प्रकारों के साथ, जानकारी के किसी भी दो टुकड़ों को देखते हुए, कोई भी तीसरे की गणना कर सकता है। जिसे जानकरजानकारी का टुकड़ा गणना की गई थी, हालांकि, कभी-कभी महत्वपूर्ण हो सकती है। उदाहरण के लिए, मान लें कि एक घटना "17:00 UTC, समय क्षेत्र -5, स्थानीय समय 12:00 बजे" के रूप में दर्ज की गई है, और एक बाद में पता चलता है कि समय क्षेत्र -6 होना चाहिए था। यदि कोई जानता है कि UTC को सर्वर से रिकॉर्ड किया गया था, तो रिकॉर्ड को "18:00 UTC, समय क्षेत्र -6, स्थानीय समय 12:00 बजे" को सही किया जाना चाहिए; अगर किसी ने घड़ी में स्थानीय समय के अनुसार "17:00 UTC, समय क्षेत्र -6, स्थानीय समय सुबह 11:00" होना चाहिए। यह जानने के बिना कि क्या वैश्विक या स्थानीय समय को "अधिक विश्वसनीय" माना जाना चाहिए, हालांकि, यह जानना संभव नहीं है कि कौन सा सुधार लागू होना चाहिए। यदि, हालांकि, रिकॉर्ड रखा गया था कि किस समय को निर्दिष्ट किया गया था, समय क्षेत्र में परिवर्तन दूसरे को बदलते समय उस अकेले को छोड़ सकता है।


0

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

इस तरह के संरक्षण में निर्माण करना ठीक है, अगर वर्ग में ऐसा कोई दर्शक है। लेकिन जब उपयोगकर्ता आपकी कक्षा में किसी फ़ंक्शन को कॉल लिखता है, तो वे आपके निष्पादन-समय बैंक खाते के साथ आप पर भरोसा कर रहे हैं।

यहाँ मैं बहुत कुछ देख रहा हूँ:

  1. वस्तुओं में एक "संशोधित" बिट है अगर वे किसी भी अर्थ में, आउट-ऑफ-डेट हैं। पर्याप्त सरल है, लेकिन तब उनके पास अधीनस्थ वस्तुएं होती हैं, इसलिए "संशोधित" होने के लिए यह एक सीधा कार्य है जो सभी अधीनस्थ वस्तुओं पर निर्भर करता है। तब अगर अधीनस्थ वस्तुओं की कई परतें हों (कभी-कभी एक ही वस्तु को एक से अधिक बार साझा करना) सरल हो तो "संशोधित" संपत्ति का "प्राप्त करें" निष्पादन समय के एक स्वस्थ अंश को समाप्त कर सकता है।

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

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

तो जाओ आंकड़ा।


0

"गणना करें या नहीं" या "प्रदर्शन की जानकारी" जैसे कार्यान्वयन विवरणों को जोड़ने से कोड रखने और सिंक में डॉक्टर को अलग करने के लिए अधिक अंतर होता है

उदाहरण:

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

बेशक, यह एक कोड अनुरक्षक के लिए कोड प्रलेखन से सभी महत्वपूर्ण infos प्राप्त करने के लिए अच्छा है, लेकिन मैं प्रलेखन की तरह दान करता हूं जो कुछ दावा करता है जो अब मान्य नहीं है (कोड के साथ सिंक से बाहर)


0

जैसा कि स्वीकृत जवाब निष्कर्ष पर आता है:

इसलिए: दस्तावेज़ प्रदर्शन समस्याएँ।

और आत्म प्रलेखित कोड बेहतर दस्तावेज़ीकरण से माना जाता है कि यह इस प्रकार है कि विधि का नाम चाहिए किसी भी असामान्य प्रदर्शन के परिणामों राज्य।

तो अभी भी Person.ageहै return current_year - self.birth_dateलेकिन अगर विधि उम्र की गणना करने के लिए एक लूप का उपयोग करता है (हाँ):Person.calculateAge()

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