लेख में दो भाग होते हैं। पहले भाग
में प्रोटोबॉफ़ में बहुरूपता पर लेख का एक नि: शुल्क रीटेलिंग है। दूसरा भाग फ्रेमवर्क के साथ काम करने के लिए स्व-निर्मित "साइकिल" के
कष्टप्रद विज्ञापन के लिए समर्पित है।
अद्यतन : जैसा कि टिप्पणियों में सही लिखा गया है, मैंने एक ढेर में विरासत और बहुरूपता को मिलाया। बहुत सकल त्रुटियों को हटाने और नए लोगों को जोड़ने के लिए , मैंने पाठ को थोड़ा बदल दिया। इसलिए, अगर यह आपको लगता है कि कुछ टिप्पणी पाठ से संबंधित नहीं है, तो सबसे अधिक संभावना है कि यह केवल पिछले संस्करण को संदर्भित करता है। मैं इस असुविधा के लिए माफी मांगता हूं।
एनबी : लेख इस सवाल का जवाब नहीं देता है कि "Google प्रोटोकॉल बफ़र्स क्या है" और किसी विशिष्ट प्रोग्रामिंग भाषा से बंधा नहीं है।
तो, समस्या का बयान:
- प्रोटोकॉल बफ़र्स के साथ काम करते समय बहुरूपता कैसे लागू करें?
- संदेशों के साथ एक बड़ी फ़ाइल होने पर, आवश्यक डेटा को कैसे खोजना और खोजना है?
एनबी: यहां, अंग्रेजी शब्द संदेश के बजाय, "संदेश" शब्द या "संरचना" शब्द का उपयोग किया जाएगा। बस कुछ वाक्यों में, शब्द "संदेश" किसी भी तरह से अजीब लगता है।
भाग I: बहुरूपता
मान लीजिए कि हमारे प्रोटोकॉल में तीन वर्ग के ऑब्जेक्ट हैं: स्क्वायर, सर्कल और बहुभुज। यह भी मान लीजिए कि उन सभी के पास एक रंग क्षेत्र और एक आईडी फ़ील्ड है। इस स्थान पर, हमारे पास आकार के सामान्य पूर्वजों से उन्हें प्राप्त करने और
वांछित बहुरूपता प्राप्त करने के कई कारण हैं (अच्छी तरह से, या कम से कम आधार प्रकार का उपयोग करके किसी ऑब्जेक्ट को संदर्भित करने की क्षमता)। और, शायद, अगर हमने विरासत के समर्थन के साथ एक भाषा में लिखा है, तो हमारा कोड निम्नानुसार दिखेगा:
छद्म कोडenum Color { RED, GREEN, BLUE } struct Point { int x; int y; } struct Shape { int id; Color color; } struct Square extends Shape { Point corner; int width; } struct Circle extends Shape { Point center; int radius; } struct Polygon extends Shape { Point [] points; }
दुर्भाग्य से, Google प्रोटोकॉल बफ़र्स पदानुक्रम का समर्थन नहीं करते हैं। जॉन पैरीज़ इस सीमा के लिए तीन वर्कअराउंड
मानते हैं।
वैकल्पिक क्षेत्रों का उपयोग करना
इस दृष्टिकोण के साथ, हम प्रत्येक उत्तराधिकारी वर्ग के लिए एक अलग संरचना बनाते हैं, और आकृति संरचना में प्रत्येक मामले के लिए वैकल्पिक क्षेत्र होते हैं।
इस दृष्टिकोण में कई गंभीर कमियां हैं:
- आप आधार वर्ग को बदले बिना एक नया वर्ग उत्तराधिकारी नहीं बना सकते। संयोग से, यदि आप किसी और के प्रोटोकॉल का विस्तार करते हैं, तो यह एक समस्या बन सकती है।
- आप (स्क्वायर और सर्कल) दोनों क्षेत्रों को शुरू करके एक अज्ञात स्क्वायर सर्कल बना सकते हैं।
- प्राप्त प्रकार को निर्धारित करने के लिए, आपको कोड लिखना होगा जो खेतों की उपस्थिति के लिए जांच करता है।
geom-1.proto enum Color { RED = 1; GREEN = 2; BLUE = 3; } message Point { required fixed32 x = 1; required fixed32 y = 2; } message Square { required Point corner = 1; required fixed32 width = 2; } message Circle { required Point center = 1; required fixed32 radius = 2; } message Polygon { repeated Point points = 1; } message Shape { required TYPE type = 1; required fixed32 id = 2; optional Color color = 3;
नेस्टेड सीरियलाइजेशन
एक अन्य दृष्टिकोण में वारिस के लिए सामान्य क्षेत्रों के साथ एक शेप स्ट्रक्चर तैयार करना और दूसरा क्षेत्र जोड़ना है जहां वारिस के क्रमबद्ध क्षेत्र पहले से ही झूठ बोलते हैं।
यह सबसे सफल विकल्प भी नहीं है, क्योंकि "धारावाहिक"
स्वचालित रूप से उपवर्ग क्षेत्र की सामग्री को "अनपैक" नहीं
करेगा , और तदनुसार अखंडता जांच नहीं की जाएगी।
वैसे भी, यह किसी भी तरह से सुंदर नहीं है।
geom-2.proto enum TYPE { SQUARE = 1; CIRCLE = 2; POLYGON = 3; } enum Color { RED = 1; GREEN = 2; BLUE = 3; } message Point { required fixed32 x = 1; required fixed32 y = 2; } message Square { required Point corner = 1; required fixed32 width = 2; } message Circle { required Point center = 1; required fixed32 radius = 2; } message Polygon { repeated Point points = 1; } message Shape { required TYPE type = 1; required fixed32 id = 2; optional Color color = 3;
नेस्टेड एक्सटेंशन्स
तीसरा (अनुशंसित) दृष्टिकोण पहले के समान है, लेकिन वैकल्पिक क्षेत्रों के बजाय नेस्टेड एक्सटेंशन का उपयोग किया जाता है। स्क्वायर सर्कल का मुकाबला करने के लिए, टाइप फ़ील्ड दर्ज किया जाता है।
geom-final.proto enum TYPE { SQUARE = 1; CIRCLE = 2; POLYGON = 3; } enum Color { RED = 1; GREEN = 2; BLUE = 3; } message Point { required fixed32 x = 1; required fixed32 y = 2; } message Shape { required TYPE type = 1; required fixed32 id = 2; optional Color color = 3; extensions 4 to max; } message Square { extend Shape { required Square shape = 5; } required Point corner = 1; required fixed32 width = 2; } message Circle { extend Shape { required Circle shape = 6; } required Point center = 1; required fixed32 radius = 2; } message Polygon { extend Shape { required Polygon shape = 7; } repeated Point points = 1; }
आइए इस दृष्टिकोण के लाभों पर करीब से नज़र डालें।
- वैकल्पिक फ़ील्ड के बजाय एक्सटेंशन का उपयोग करना आपको इसकी अनुमति देता है:
- "इनहेरिट" अन्य लोगों की परिभाषा (प्रोटोकॉल)
- अन्य फ़ाइलों में "वारिस" वर्गों का वर्णन करें। जब ऐसे कई वर्ग हैं, तो यह महत्वपूर्ण हो सकता है।
- यह तथ्य कि एक्सटेंशन नेस्टेड हैं, आपको फ़ील्ड्स को एक ही नाम देने की अनुमति देता है, क्योंकि वास्तव में वे अलग-अलग लेक्सिकल स्कोप में होंगे। हमारे उदाहरण में, ये Square.shape, Circle.shape और Polygon.shape हैं; टेम्पलेट समर्थित भाषाओं में, बहुत सुविधाजनक है।
- दूसरे दृष्टिकोण के विपरीत, सब कुछ रूपरेखा द्वारा deserialized होगा।
भाग II: खोज
और इसलिए, हमारे पास संदेश संरचना (geom.proto) के विवरण के साथ एक फ़ाइल है। हमारे कार्यक्रम ने काम किया और स्वयं संदेशों के साथ एक बड़ी फ़ाइल बनाई। मैं इसमें आवश्यक जानकारी प्राप्त करना चाहूंगा, लेकिन यह हमेशा एक सरल पाठ खोज के साथ संभव नहीं है।
उदाहरण के लिए:
- समन्वित कुल्हाड़ियों को भेदते हुए वृत्त ज्ञात कीजिए।
- बिंदुओं के खाली सेट के साथ बहुभुज ढूंढें
- 10 से अधिक अंकों के साथ बहुभुज ढूंढें।
सहमत हूँ, नियमित grep यहाँ हमारी मदद नहीं करेगा।
बेशक, ऐसे प्रत्येक कार्य के लिए एक छोटा सा कार्यक्रम लिखना आसान है, जो निर्दिष्ट गुणों के साथ फ़ाइल में आंकड़े की तलाश करेगा। हालाँकि, चूंकि हमारे पास संरचित डेटा और उसका प्रारूप है, इसलिए अपनी क्वेरी भाषा क्यों नहीं लिखें?
हम कार्यों के उदाहरणों के साथ लौटेंगे:
type == "CIRCLE" && ((center.x - radius) < 0 || (center.y - radius) < 0))
// समन्वित अक्षों को type == "CIRCLE" && ((center.x - radius) < 0 || (center.y - radius) < 0))
वाले वृत्त ज्ञात करें।type == "POLYGON" && #points == 0
// type == "POLYGON" && #points == 0
को बिंदुओं के खाली सेट के साथ खोजेंtype == "POLYGON" && #points > 10
// 10 से अधिक बिंदुओं वाले बहुभुज ढूंढें।
यह सब, और बहुत कुछ एक
स्व-निर्मित बाइक बनाने में सक्षम है।
और यह भी, वह कर सकता है- द्विआधारी से पाठ प्रारूप में फ़ाइलों को स्थानांतरित करें और इसके विपरीत
- संदेशों से केवल कुछ फ़ील्ड काटें और प्रिंट करें
- एक अनुरोध में लगातार कई संदेशों का उपयोग करें। उदाहरण के लिए, हलकों के तुरंत बाद सभी वर्गों को ढूंढें।
मुझे उम्मीद है कि बाइक को अपना उपयोगकर्ता मिल जाएगा, और इसके साथ, बाइक के सिंटैक्स और क्षमताओं के बारे में एक विस्तृत विषय की आवश्यकता होगी।
आपका धन्यवाद