यह एक सामान्य सी ++ डिजाइन सवाल है।सी ++ में पारदर्शी रूप से विभिन्न प्रोटोकॉल संस्करणों को कैसे संभालें?
मैं एक ऐसा एप्लिकेशन लिख रहा हूं जो क्लाइंट/सर्वर मॉडल का उपयोग करता हो। अभी मैं सर्वर-साइड लिख रहा हूं। कई ग्राहक पहले से मौजूद हैं (कुछ स्वयं द्वारा लिखे गए हैं, अन्य तृतीय पक्षों द्वारा)। समस्या यह है कि ये मौजूदा ग्राहक विभिन्न प्रोटोकॉल संस्करणों का उपयोग करते हैं (वर्षों में 2-3 प्रोटोकॉल परिवर्तन हुए हैं)।
जब से मैं कर रहा हूँ सर्वर को फिर से लिखकर, मैंने सोचा कि यह एक महान मेरे कोड इस तरह है कि मैं कई अलग अलग प्रोटोकॉल संस्करणों पारदर्शी रूप से संभाल कर सकते हैं डिजाइन करने के लिए समय होगा। सभी प्रोटोकॉल संस्करणों में, क्लाइंट से पहले संचार में प्रोटोकॉल संस्करण होता है, इसलिए प्रत्येक क्लाइंट कनेक्शन के लिए, सर्वर जानता है कि किस प्रोटोकॉल को बात करने की आवश्यकता है।
अनुभवहीन यह करने के लिए विधि कूड़े को इस तरह बयान के साथ कोड है:
if (clientProtocolVersion == 1)
// do something here
else if (clientProtocolVersion == 2)
// do something else here
else if (clientProtocolVersion == 3)
// do a third thing here...
यह समाधान बहुत खराब है, निम्नलिखित कारणों के लिए:
- जब मैं एक जोड़ने नया प्रोटोकॉल संस्करण, मुझे स्रोत पेड़ में हर जगह मिलना है कि यदि कथन का उपयोग किया जाता है, और नई कार्यक्षमता जोड़ने के लिए उन्हें संशोधित करें।
- एक नए प्रोटोकॉल संस्करण के साथ आता है, और प्रोटोकॉल संस्करण के कुछ भागों एक और संस्करण के रूप में ही कर रहे हैं, मैं अगर बयान संशोधित करने की जरूरत है ताकि वे
if (clientProtoVersion == 5 || clientProtoVersion == 6)
पढ़ें। - मुझे यकीन है कि यह खराब डिज़ाइन क्यों है और अधिक कारण हैं, लेकिन मैं अभी उनके बारे में नहीं सोच सकता।
मैं जो खोज रहा हूं वह सी ++ लैंगेज की विशेषताओं का उपयोग करके समझदारी से विभिन्न प्रोटोकॉल को संभालने का एक तरीका है। मैंने टेम्पलेट कक्षाओं का उपयोग करने के बारे में सोचा है, संभवतः प्रोटोकॉल संस्करण निर्दिष्ट करने वाले टेम्पलेट पैरामीटर के साथ, या शायद एक वर्ग विरासत, प्रत्येक अलग प्रोटोकॉल संस्करण के लिए एक वर्ग ...
मुझे यकीन है कि यह एक बहुत ही सामान्य डिजाइन पैटर्न है , इतने सारे लोगों को पहले यह समस्या होनी चाहिए थी।
संपादित करें:
आप में से कई लोग एक विरासत पदानुक्रम का सुझाव दिया है, शीर्ष पर सबसे पुराना प्रोटोकॉल संस्करण के साथ, इस तरह (मेरे ASCII आर्ट के लिए क्षमा करें):
IProtocol
^
|
CProtoVersion1
^
|
CProtoVersion2
^
|
CProtoVersion3
... यह पुन: उपयोग के मामले में करने के लिए एक समझदार चीज की तरह लगता है। हालांकि, क्या होता है जब आपको प्रोटोकॉल का विस्तार करने और मौलिक रूप से नए संदेश प्रकार जोड़ने की आवश्यकता होती है? अगर मैं IProtocol
में आभासी तरीके जोड़, और CProtocolVersion4
में इन नए तरीकों को लागू करने, कैसे इन नए तरीकों पहले प्रोटोकॉल संस्करणों में इलाज कर रहे हैं? मुझे लगता है कि मेरे विकल्प हैं:
- डिफ़ॉल्ट कार्यान्वयन को NO_OP (या संभवतः किसी संदेश को लॉग ऑन करें) बनाएं। हालांकि यह एक बुरा विचार की तरह लगता है
- , एक अपवाद फेंक के रूप में भी मैं इसे टाइप कर रहा हूँ।
- ... कुछ और?
EDIT2:
उपरोक्त मुद्दों कोइसके अलावा, क्या होता है एक नए प्रोटोकॉल संदेश एक पुराने संस्करण की तुलना में अधिक इनपुट की आवश्यकता है जब? उदाहरण के लिए:
protocl संस्करण 1 में, मैं हो सकता है:
ByteArray getFooMessage(string param1, int param2)
और प्रोटोकॉल संस्करण 2 में मैं चाह सकते हैं:
ByteArray getFooMessage(string param1, int param2, float param3)
दो अलग अलग प्रोटोकॉल संस्करणों अब अलग-अलग विधि हस्ताक्षर, जो ठीक है, सिवाय इसके कि यह मुझे सभी कॉलिंग कोड से गुज़रने के लिए मजबूर करता है और प्रोटोकॉल संस्करण का उपयोग करने के आधार पर, 2 पैरा से 3 पैरा के साथ सभी कॉल बदलता है, जिसे मैं उपयोग करता हूं मैं पहली जगह से बचने की कोशिश कर रहा हूँ!
प्रोटोकॉल संस्करण जानकारी को आपके शेष कोड से अलग करने का सबसे अच्छा तरीका क्या है, जैसे वर्तमान प्रोटोकॉल के विनिर्देश आपके से छिपाए गए हैं?
दरअसल रणनीति पैटर्न सबसे संभावित दृष्टिकोण है, तो आप शायद फैक्टरी के साथ गठबंधन करना चाहते हैं जो आपके द्वारा उपयोग किए जा रहे संस्करण के लिए सही 'रणनीति' प्रदान करने के लिए जिम्मेदार होगा। –