OO में क्या संदेश गुजर रहा है?


35

मैं OO प्रोग्रामिंग का अध्ययन कर रहा हूं, मुख्य रूप से C ++, C # और Java में। मुझे लगा कि मेरे पास इनकैप्सुलेशन, इनहेरिटेंस और पॉलिमोर्फिज्म (साथ ही इस साइट पर बहुत सारे प्रश्न पढ़ने के बारे में) की मेरी समझ के साथ इस पर अच्छी पकड़ है।

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

मेरे प्रश्न हैं:

  • संदेश क्या है? (क्या कोई व्यावहारिक उदाहरण दे सकता है?)
  • क्या C ++, C # या Java में इस "संदेश पासिंग" का कोई समर्थन है?

4
मैंने कुछ समय पहले इस सवाल का जवाब दिया: stackoverflow.com/a/3104741/10259
Frank Shearar

1
क्या आपने विकिपीडिया लेख पढ़ा ?
यानिस

4
मेरी विनम्र राय में, ऑब्जेक्टिव-सी मुख्य धारा की भाषा के रूप में योग्य होगा। कम से कम C # जितना।
मौविसील

मैं इस बात से सहमत हूं, मैं अपने अनुभव से "मुख्यधारा" भाषाओं का मंचन कर रहा था
टॉम

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

जवाबों:


60

संदेश क्या है? (क्या कोई व्यावहारिक उदाहरण दे सकता है?)

संदेश पासिंग का सीधा सा मतलब है कि (बहुत अमूर्त स्तर पर) प्रोग्राम एक्जीक्यूशन का मूलभूत तंत्र एक दूसरे को संदेश भेजने वाली वस्तुएं हैं। महत्वपूर्ण बिंदु यह है कि स्रोत कोड में इन संदेशों का नाम और संरचना पहले से तय नहीं है और स्वयं अतिरिक्त जानकारी हो सकती है। यह मूल रूप से "ऑब्जेक्ट ओरिएंटेड प्रोग्रामिंग" के रूप में परिकल्पित एलन के का एक महत्वपूर्ण हिस्सा है।

क्या C ++, C # या Java में इस "संदेश पासिंग" का कोई समर्थन है?

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

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

ग्रूवी में एक उदाहरण जो इस अवधारणा की शक्ति को प्रदर्शित करता है:

def xml = new MarkupBuilder(writer)
xml.records() {
  car(name:'HSV Maloo', make:'Holden', year:2006) {
    country('Australia')
    record(type:'speed', 'Production Pickup Truck with speed of 271kph')
  }
}

इस XML का उत्पादन करेगा:

<records>
  <car name='HSV Maloo' make='Holden' year='2006'>
    <country>Australia</country>
    <record type='speed'>Production Pickup Truck with speed of 271kph</record>
  </car>
</records>

ध्यान दें कि records, car, countryऔर recordवाक्य रचना विधि कॉल कर रहे हैं, लेकिन वहाँ है कि नाम में परिभाषित करने का कोई तरीके हैं MarkupBuilder। इसके बजाय, इसमें एक कैटचेल संदेश हैंडलर है जो सभी संदेशों को स्वीकार करता है और संदेश के नामों को एक्सएमएल तत्व, मापदंडों के रूप में मापदंडों और बाल तत्वों के रूप में बंद होने की व्याख्या करता है।


बिंदु उत्तर के लिए सीधे +1। कोड उदाहरण के लिए स्वीकार किया गया। आपकी मदद के लिए धन्यवाद :)
टॉम

तो क्या यह केवल एक सरल sendMessage(property_name, Array of arguments)और getMessage(property_name, Array of arguments)स्थिर भाषाओं में लागू नहीं किया जा सकता है ?
पचेरियर

1
@ स्पेसर: यकीन है, लेकिन यह दोनों दृष्टिकोणों के नुकसान को जोड़ रहा है - आप प्रकार की सुरक्षा खो देते हैं और अभी भी "SendMessage" आपको हर जगह कोड को प्रदूषित कर रहा है, इसलिए आपको सुरुचिपूर्ण सिंटैक्स नहीं मिलता है।
माइकल बोर्गवर्ड

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

@ एडमडर्नर: आप सही कह रहे हैं, मैंने इसे ठीक कर दिया है।
माइकल बोर्गवर्ड

28

संदेश पास करना किसी वस्तु को किसी अन्य वस्तु (या संभवतः स्वयं) को प्राप्त करने के लिए OO कोड में आवश्यकता को संभालने का एक अलग तरीका है।

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

public void doSomething ( String input )
...
other_object.dosomething ( local )

इसके बाद सांख्यिकीय रूप से टाइप की गई भाषाओं के लिए संकलक फिर बुलाए जा रहे प्रकार की जाँच कर सकता है और पुष्टि कर सकता है कि विधि घोषित कर दी गई है। गतिशील रूप से टाइप की गई भाषाओं के लिए फिर रनटाइम पर किया जाता है।

लेकिन संक्षेप में यह होता है कि कोड के एक विशिष्ट ब्लॉक में चर का एक बंडल भेजा जाता है।

संदेश देना

मैसेज पासिंग लैंग्वेजेज (जैसे ऑब्जेक्टिव सी) में तरीकों के बजाय रिकवर होते हैं, लेकिन मोटे तौर पर उन्हें परिभाषित करने और उन्हें कॉल करने का तरीका एक जैसा ही होता है - अंतर यह है कि जिस तरह से इसे हैंडल किया जाता है।

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

परिणामस्वरूप C ++ / Java से चलते समय पाई जाने वाली विषमताओं में से एक -> Objective C यह समझ रही है कि आप उस वस्तु पर "विधि को कॉल कर सकते हैं" जिसे संकलन-समय प्रकार पर घोषित नहीं किया गया था, और उस पर मौजूद भी नहीं था रन-टाइम प्रकार ... और यह कि कॉल अपवाद के रूप में नहीं फेंका जाएगा, लेकिन वास्तव में एक परिणाम वापस पारित किया जा रहा है।

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

हालाँकि ऐसा लगता है कि डेवलपर द्वारा अतिरिक्त जाँच की आवश्यकता की कीमत पर उन्हें लगता है कि वे जो कॉल कर रहे हैं वे सही प्रकार के साथ सही ऑब्जेक्ट पर हैं और सही क्रम में सही पैरामीटर पास कर रहे हैं, क्योंकि कंपाइलर नहीं हो सकता है आपको चेतावनी देता है और यह रनटाइम पर पूरी तरह से चलेगा (बस एक डिफ़ॉल्ट प्रतिक्रिया लौटाएगा)। यकीनन अतिरिक्त लुक-अप और पैरामटर पासिंग से एक प्रदर्शन हिट है।

इन दिनों, डायनामिक रूप से टाइप की गई भाषाएं कम मुद्दों के साथ ओओए संदेश के कई लाभ दे सकती हैं।


1
मुझे यह उत्तर पसंद है - अंतर और उनके निहितार्थ बताते हैं।
हैप्पीकट

@Gavin, तो यह है कि वास्तव में PHP के और जावास्क्रिप्ट के रूप में एक ही गतिशील विधि हैंडलर ?
पचेरियर

11

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

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

एक अजीब उदाहरण वेब है। HTTP एक संदेश पासिंग सिस्टम है - आप एक सर्वर प्रक्रिया के लिए एक कमांड क्रिया और एक 'डेटा पैकेट' पास करते हैं। (उदा। http: \ myserver \ url प्राप्त करें) न तो आपका ब्राउज़र, और न ही वेबसर्वर आपके द्वारा भेजे जाने वाले डेटा, या जहाँ आप इसे भेजते हैं, उसके बारे में कुछ भी परवाह नहीं करता है। सर्वर उस कोड को पास करेगा जो डेटा का एक और 'पैकेट' पैकेज करेगा और आपको इसे वापस भेज देगा। इस प्रणाली के किसी भी घटक को दूसरों के काम के बारे में कुछ भी पता नहीं है या वे क्या करते हैं, वे सिर्फ संदेश संचार के लिए उपयोग किए जाने वाले प्रोटोकॉल को जानते हैं।


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