किन कारणों से आप स्विफ्ट में प्रत्येक प्रतिनिधि के लिए एक अलग वर्ग एक्सटेंशन का उपयोग करेंगे?


13

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

वर्ग विस्तार के अंदर प्रतिनिधि कॉलबैक:

extension LogsViewController : UIPopoverPresentationControllerDelegate {
    func adaptivePresentationStyleForPresentationController(controller: UIPresentationController, traitCollection: UITraitCollection) -> UIModalPresentationStyle {
        ...
    }
}

वर्ग के भीतर समाहित होने के विपरीत:

वर्ग के अंदर प्रतिनिधि कॉलबैक:

class LogsViewController : UITableViewController, UIPopoverPresentationControllerDelegate {
    func adaptivePresentationStyleForPresentationController(controller: UIPresentationController, traitCollection: UITraitCollection) -> UIModalPresentationStyle {
        ...
    }
}

मुझे यह अजीब और दिलचस्प लगा। उसके पास एक फाइल है, जो केवल "LogsViewControllerExtension.swift" LogsViewController क्लास पर एक्सटेंशन के लिए समर्पित है और प्रत्येक प्रतिनिधि प्रोटोकॉल के लिए एक अलग एक्सटेंशन है: UITableViewDataSource, UISplititDelegate, आदि:

कई वर्ग एक्सटेंशन प्रत्येक w / डेलिगेट कॉलबैक को अपनी फाइल के अंदर रखते हैं:

extension LogsViewController: UISplitViewControllerDelegate {
    ... callbacks
}

extension LogsViewController : UIPopoverPresentationControllerDelegate {
    ... callbacks
}

क्यों?

ऐसा करने के क्या फायदे हैं? मैं देख सकता हूं कि इसे अलग करने के लिए यह थोड़ा अधिक पठनीय कहां हो सकता है, लेकिन साथ ही यह अप्रत्यक्ष स्तर का है। क्या ऐसे ओओ सिद्धांत हैं जो इसके समर्थन में हैं या ऐसा करने के खिलाफ हैं?


1
आप इस तरह की बहुत सारी संरचना लिख ​​सकते हैं जो ओओ के सिद्धांतों द्वारा मौलिक रूप से समर्थित है लेकिन फिर भी अतिरंजना के लिए दोषी है।
रॉबर्ट हार्वे

1
@RobertHarvey सच है, लेकिन क्या आप इसका मतलब निकाल रहे हैं कि मैंने जो उदाहरण कोड यहां दिखाया है, वह अतिरंजना का एक रूप है? आईओएस विकास में डेलिगेशन एक सामान्य पैटर्न है। इसके अलावा, चाहे आप क्लास एक्सटेंशन का उपयोग करते हैं या उसके भीतर कोड नहीं बदलते हैं, इसलिए यह पुन: (/ ओवर) के बजाय कोड रीस्ट्रक्चरिंग की तरह अधिक होगा -इंजीनियरिंग
morbidhawk

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

जवाबों:


15

मुझे नहीं पता कि आपने क्यों कहा कि यह अप्रत्यक्ष स्तर जोड़ता है। हो सकता है कि आप पारंपरिक अर्थ की तुलना में कुछ अलग मतलब रखते हैं, क्योंकि ऐसा करने से कोई अतिरिक्त अप्रत्यक्ष निर्माण नहीं होता है। लेकिन ऐसा क्यों?

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

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

और किसी भी दर पर, लोग अक्सर वसा दृश्य नियंत्रकों के बारे में शिकायत करते हैं और इस तरह से एक दृश्य नियंत्रक को तोड़ने से इसे बेहतर ढंग से व्यवस्थित रखने में मदद मिलती है, भले ही यह वास्तव में दृश्य नियंत्रक को पतला न करे।


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

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

2

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

यह कहें कि आपके पास didCopyTextउदाहरण के लिए एक प्रोटोकॉल है। आप इसे लागू करेंगे:

protocol didCopyText {
  var charachtersCount: Int {get}
  func addToClipboardWith(text: String)
}

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

protocol didCopyText {
var charachtersCount: Int {
    get {
     // implementation
    }
}
func addToClipboardWith(text: String) {
      // implementation
 }
}

प्रोटोकॉल के गुणों और विधियों के कार्यान्वयन के साथ। अब, कोई भी वर्ग इस प्रोटोकॉल के अनुरूप है, उसी कार्यान्वयन का उपयोग करेगा।


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

1

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

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

जब तक ये एक्सटेंशन सही मायने में बड़े नहीं होंगे, तब तक मैं उन्हें अलग-अलग फाइलों में नहीं डालूँगा।

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