विधि मापदंडों के बजाय कंस्ट्रक्टर को डेटा पास करते समय एक वर्ग की अवधारणा कैसे बदल जाती है?


12

मान लीजिए कि हम एक पार्सर बना रहे हैं। एक कार्यान्वयन हो सकता है:

public sealed class Parser1
{
    public string Parse(string text)
    {
       ...
    }
}

या हम इसके बजाय पाठक को पास कर सकते हैं:

public sealed class Parser2
{
    public Parser2(string text)
    {
       this.text = text;
    }

    public string Parse()
    {
       ...
    }
}

उपयोग दोनों मामलों में सरल है, लेकिन अन्य की तुलना में पैरामीटर इनपुट को सक्षम करने का क्या मतलब है Parser1? जब मैं एपीआई को देखता हूं तो मैंने एक साथी प्रोग्रामर को क्या संदेश भेजा है? इसके अलावा, क्या कुछ मामलों में कोई तकनीकी फायदे / नुकसान हैं?

एक और सवाल तब उठता है जब मुझे एहसास होता है कि दूसरे कार्यान्वयन में एक इंटरफ़ेस काफी अर्थहीन होगा:

public interface IParser
{
    string Parse();
}

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


यह पहली बार है जब मैंने OO के शब्दार्थों को वास्तव में व्यक्त करने के बारे में कुछ उपयोगी प्रश्नोत्तर देखे हैं। अब तक यह सब मेरे लिए, बस चीनी की मात्रा है।

जवाबों:


11

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

कंस्ट्रक्टर में आपको जो पैरामीटर पास करने की आवश्यकता होती है, वे ऐसे पैरामीटर होते हैं जिनका कोई समझदार डिफ़ॉल्ट मान नहीं होता है और यदि आपकी कक्षा अपरिवर्तनीय (या वास्तव में struct) है तो सभी-नॉन डिफ़ॉल्ट गुणों को पास करना होगा।

अपने दो उदाहरण के बारे में:

  • यदि आप textकंस्ट्रक्टर के पास जाते हैं , तो यह संकेत देता है कि Parser2क्लास को विशेष रूप से पाठ के उस उदाहरण को पार्स करने के लिए बनाया जाएगा। यह एक विशिष्ट पार्सर होगा। यह आम तौर पर तब होता है जब कक्षा का निर्माण बहुत महंगा या सूक्ष्म होता है, एक RegEx को कंस्ट्रक्टर में संकलित किया जा सकता है, इसलिए एक बार जब आप एक उदाहरण लेते हैं तो आप संकलन की लागत का भुगतान किए बिना इसे फिर से उपयोग कर सकते हैं; एक और उदाहरण PRNG को इनिशियलाइज़ कर रहा है - अगर यह शायद ही कभी किया जाए तो बेहतर है।
  • यदि आप textविधि से गुजरते हैं , तो यह संकेत देता है कि Parser1कॉल द्वारा विभिन्न ग्रंथों को पार्स करने के लिए पुन: उपयोग किया जा सकता है।

3
मैं जोड़ूंगा कि एक कमजोर, संकेत है कि Parser1 राज्य को बनाए रखता है - यानी कि पाठ का एक विशेष स्ट्रिंग पहले परिणाम के आधार पर अलग-अलग परिणाम उत्पन्न कर सकता है। यह जरूरी नहीं है, लेकिन यह हो सकता है।
जोमेरो

8

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

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

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


+1। सामंजस्य यह है कि मैं कैसे तय करता हूं कि यह विधि या निर्माता पर है।
शाम 5:51

4

उपयोग दोनों मामलों में सरल है, लेकिन अन्य की तुलना में Parser1 के पैरामीटर इनपुट को सक्षम करने का क्या मतलब है?

इसका एक मौलिक डिज़ाइन शिफ्ट है। और डिजाइन इरादे और अर्थ को व्यक्त करना चाहिए। क्या आपको पार्स करने के लिए हर स्ट्रिंग के लिए अलग-अलग ऑब्जेक्ट्स की आवश्यकता है? दूसरे शब्दों में, हमें स्ट्रिंग के साथ पार्सर के उदाहरण और स्ट्रिंग के साथ एक और उदाहरण की आवश्यकता क्यों है? यह पार्स (आईएनजी) और दिए गए तार के बारे में क्या है कि दोनों को एक साथ रहना और मरना होगा? यह मानते हुए कि "अंतर्निहित [पार्सिंग] कार्यान्वयन" (जैसा कि रॉबर्ट हार्वे कहते हैं) नहीं बदलता है, कोई मतलब नहीं है। और फिर भी इसके संदिग्ध आई.एम.एच.ओ.

विधि मापदंडों के बजाय कंस्ट्रक्टर को डेटा पास करते समय एक वर्ग की अवधारणा कैसे बदल जाती है?

निर्माता पैरामीटर मुझे बताते हैं कि इन चीजों को एक वस्तु के लिए आवश्यक है। उनके बिना उचित राज्य की गारंटी नहीं है। इसके अलावा, मुझे पता है कि कैसे / क्यों एक पार्सर मौलिक रूप से दूसरे से अलग है।

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

एक और सवाल तब उठता है जब मुझे एहसास होता है कि दूसरे कार्यान्वयन में एक इंटरफ़ेस काफी अर्थहीन होगा:

एपीआई के रूप में एक इंटरफ़ेस, क्लाइंट कोड के लिए तरीके और गुण हैं। public interface { ... }विशेष रूप से लिपटे मत रहो । तो इंटरफ़ेस का अर्थ या तो या कंस्ट्रक्टर बनाम विधि पैरामीटर दुविधा में है, न कि public interface Iparserबनामpublic sealed class Parser

sealedवर्ग अजीब है। यदि मैं अलग-अलग पार्सर कार्यान्वयनों के बारे में सोच रहा हूं - आपने "इपरसेर" का उल्लेख किया है - तो विरासत मेरा पहला विचार है। यह मेरी सोच में एक स्वाभाविक वैचारिक विस्तार है। IE सभी ParserXs मौलिक रूप से Parsers हैं। इसे और कैसे कहें? ... एक जर्मन शेपर्ड एक कुत्ता (विरासत) है, लेकिन मैं अपने तोते को छाल (एक कुत्ते की तरह काम कर सकता हूं - "इंटरफ़ेस") को प्रशिक्षित कर सकता हूं; लेकिन पोली एक कुत्ता नहीं है, केवल दिखावा कर रहा है, जिसने कुत्ते का एक उपसमुच्चय सीखा है। कक्षाएं, सार या अन्यथा, इंटरफेस के रूप में अच्छी तरह से सेवा करते हैं ।


यदि यह एक तोते की तरह चलता है और एक तोते की तरह बात करता है, तो यह है ... एक बतख!

2

वर्ग के दूसरे संस्करण को अपरिवर्तनीय बनाया जा सकता है।

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


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

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

द स्कायला एंड चरीबडीस: क्या मैं OO या अपरिवर्तनीय डेटा चुनता हूं? मैंने ऐसा पहले कभी नहीं सुना।

2

Parser1

डिफ़ॉल्ट कंस्ट्रक्टर के साथ बिल्डिंग करना और इनपुट टेक्स्ट को एक विधि में बदलना यह दर्शाता है कि Parser1 फिर से उपयोग करने योग्य है।

Parser2

कंस्ट्रक्टर में इनपुट टेक्स्ट पास करने का अर्थ है कि प्रत्येक इनपुट स्ट्रिंग के लिए एक नया Parser2 बनाया जाना चाहिए।


ज़रूर, इसलिए अगर हम इसे अगले स्तर पर ले जाते हैं, तो एक गैर-पुन: प्रयोज्य की तुलना में पुन: प्रयोज्य वस्तु के बारे में क्या निष्कर्ष निकालना है?
सिस्कोथेट

मैं इसके बजाय किसी भी अधिक नहीं मानूंगा, इसके बजाय प्रलेखन के लिए।
माइक पार्टनर

एक "पुन: प्रयोज्य वस्तु" जहां इसकी पहचान बदलती है, एक गैर-अनुक्रमिक है। और प्रबंधित चौखटे के साथ अर्थ है कि आपको चीजों को दूर फेंकने की ज़रूरत नहीं है, बस उन्हें अधिलेखित करें या उन्हें दायरे से बाहर जाना है, यह निश्चित रूप से अनावश्यक है। दूर का निर्माण!
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.