2013-02-14 19 views
5

उद्देश्य-सी में?प्रोटोकॉल बनाम विरासत का उपयोग करने के फायदे और नुकसान क्या हैं?

मेरे पास एक कक्षा थी और फिर मैंने फैसला किया कि मुझे एक और कक्षा चाहिए जो कि प्रथम श्रेणी की तरह हो। क्या मुझे प्रोटोकॉल का उपयोग करना चाहिए और यह सुनिश्चित करना चाहिए कि दोनों वर्ग उस प्रोटोकॉल का समर्थन करते हैं या क्या मुझे अभिभावक वर्ग बनाना चाहिए और यह तय करना चाहिए कि 2 कक्षाएं उस वर्ग से प्राप्त होती हैं?

नोट:

वर्ग हैं: व्यापार, सूची, AddressAnnotation (वर्तमान में केवल व्यापार पर ही काम करता है) और AddressAnnotationView (वर्तमान में व्यापार केवल पर ही काम करता है)। मैं वही चीज़ कैटलॉग पर काम करना चाहता हूं। BGGoogleMapCacheForAllAnnotations भी हैं जो एनोटेशन को एक साथ दबाए जाने पर प्रबंधित करते हैं (जो अब कैटलॉग और व्यवसाय के लिए पता एन्टरेशन दोनों को संभालने में सक्षम होना चाहिए। इसके अलावा BGGoogleMap व्यू कंट्रोलर भी है जो मैं एक मूल वर्ग में बदलना चाहता हूं।

+0

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

उत्तर

7

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

उदाहरण के लिए, मान लें कि आपके पास आपके गेम में Vehicle कक्षा है जो जानता है कि सभी तरह की चीजें कैसे करें, जैसे कि घूमना। यदि आप Car कक्षा बनाना चाहते हैं, तो आप शायद Vehicle कक्षा को उपclass कर सकते हैं ताकि आप इसके सभी विधि कार्यान्वयन का वारिस कर सकें; या तो उन्हें थोक का उपयोग करने या विधियों के अपने संस्करण को लागू करने के लिए, शायद सुपरक्लास के कार्यान्वयन को कॉल करने से पहले उप-वर्ग के लिए विशिष्ट कुछ कार्य निष्पादित करना। उप-वर्गीकरण तब होता है जब आप किसी भी तरीके से इसे संशोधित करते समय अपने सुपरक्लास के गुणों और व्यवहारों का उत्तराधिकारी बनना चाहते हैं। यह विशेष रूप से सच है जब कक्षा में अतिरिक्त डेटा जोड़ा जाना चाहिए, जैसे आवृत्ति चर, क्योंकि आप श्रेणियों के साथ ऐसा नहीं कर सकते हैं (हालांकि आप Class Extension के साथ कर सकते हैं, जिसे अक्सर एक निजी इंटरफ़ेस के रूप में देखा जाता है)। आम तौर पर, उप-वर्गों के परिणामस्वरूप उनके सुपरक्लास के मुकाबले अधिक विशेष उद्देश्य होते हैं।

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

//SGSprite.h 
@protocol SGSpriteDelegate 
    - (BOOL) animation:(int)animationIndex willCompleteFrameNumber:(int)frame forSprite:(id)sender; 
@end 

@interface SGSprite : NSObject 
@property (nonatomic, assign) id<SGSpriteDelegate> delegate; 
@end 

//SGViewController.h 
@interface SGViewController : UIViewController <SGSpriteDelegate> 
    //...dreadfully boring stuff 
@end 

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

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

+0

यह एक बहुत बेहतर जवाब है। –

+0

@JimThio धन्यवाद। मैंने थोड़ी देर बिताई। – Metabble

+0

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

3

कोई हैं ऐसे कई कारक जो उस निर्णय को प्रभावित कर सकते हैं। एक के लिए, जब आप कहते हैं कि दूसरी कक्षा "प्रथम श्रेणी की तरह" है, तो इसका क्या अर्थ है? क्या इसका मतलब यह है कि वे वही चीज़ों का 90% वही करेंगे रास्ता? क्या इसका मतलब यह है कि वे एक ही तरह की चीजें करेंगे, लेकिन प्रत्येक थोड़ा अलग तरीके से करेंगे?

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

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

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

+0

यह समझना आसान था। अच्छी तरह से समझाया। – viral