2012-10-29 10 views
5

मेरे पास एक कक्षा है जो ओरेकल या MySQL के साथ इंटरफ़ेस कर सकती है। कक्षा को "ओरेकल" या "माईएसक्यूएल" या कुछ अन्य पैरामीटर के कीवर्ड के साथ शुरू किया गया है जो डेटाबेस प्रकारों (प्रिंट करने के लिए, क्या अपवाद पर रोकना है या नहीं) के लिए मानक हैं।कक्षाओं को कई वर्गों में विभाजित करने के लिए सबसे पाइथोनिक तरीका

जब मैंने शुरू किया, तो आवश्यकतानुसार if Oracle do A, elif MySQL do B जोड़ने के लिए काफी आसान था, लेकिन जैसा कि मैं अधिक विशिष्ट कोड जोड़ता हूं जो केवल एक डेटाबेस प्रकार पर लागू होता है, यह बदसूरत हो रहा है। मैंने कक्षा को दो में विभाजित कर दिया है, एक ओरेकल के लिए और एक MySQL के लिए, डुप्लिकेट कोड से बचने के लिए कुछ साझा फ़ंक्शंस के साथ।

इन नए वर्गों को कॉल करने के लिए सबसे पाइथोनिक तरीका क्या है? क्या मैं एक रैपर फ़ंक्शन/क्लास बनाता हूं जो इस कीवर्ड का उपयोग करता है और सही कक्षा देता है? क्या मैं अपना पूरा कोड बदलता हूं जो पुरानी जेनेरिक क्लास को सही डीबी-विशिष्ट कक्षा को कॉल करने के लिए कहता है?

यदि आवश्यक हो तो मैं खुशी से कुछ उदाहरण कोड तैयार करूँगा, लेकिन मुझे नहीं लगता था कि यह आवश्यक था। किसी भी सहायता के लिए अग्रिम रूप से धन्यवाद!

उत्तर

4

क्या मैं एक रैपर फ़ंक्शन/क्लास बनाता हूं जो इस कीवर्ड का उपयोग करता है और सही कक्षा देता है?

यही विचार है। इस तरह के एक समारोह को फैक्ट्री फ़ंक्शन कहा जाता है:

def connect_to(db, *args): 
    if db == "MySQL": 
     return MySQL(*args) 
    elif db == "Oracle": 
     return Oracle(*args) 
    else: 
     raise ValueError("unknown database type: %r" % db) 

सुनिश्चित करें कि दोनों डेटाबेस कक्षाओं में एक ही API है। आप इसे या तो बतख टाइपिंग या सार आधार कक्षाओं (एबीसी) के साथ प्राप्त कर सकते हैं; उत्तरार्द्ध अधिकतर उपयोगी होते हैं यदि कक्षाओं के बीच कार्यक्षमता साझा की जाती है, या यदि आप isinstance करना चाहते हैं तो यह पता लगाने के लिए कि कोई ऑब्जेक्ट डेटाबेस कनेक्शन का प्रतिनिधित्व करता है या नहीं।

साझा कार्यक्षमता के मामले में, template method pattern अक्सर काम में आता है।

3

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

यह अच्छी तरह से काम करता है जब दोनों वर्ग समान रूप से व्यवहार करते हैं; लेकिन जैसे ही आप डीबी विशिष्ट विशेषताओं का उपयोग करना चाहते हैं, यह बदसूरत हो जाता है क्योंकि आपको isFeatureXSupported() (अच्छा दृष्टिकोण) या isOracle() जैसी विधियों की आवश्यकता होती है (अधिक सरल लेकिन बुरा यह ज्ञान चलाता है कि किस डीबी में सहायक वर्ग से ऐप कोड में कौन सी सुविधा है)।

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

+2

अच्छी सलाह, लेकिन जब तक कि आपकी फैक्ट्री क्लास बेस क्लास भी न हो, तो आप एक फैक्ट्री फ़ंक्शन का उपयोग भी कर सकते हैं। – Marcin

+0

फ़ैक्टरी क्लास का उपयोग करना उपयोगी होता है जब आपको इसे कॉन्फ़िगर करने की आवश्यकता होती है। अन्यथा, आपको बहुत से पैरामीटर के साथ एक फ़ंक्शन मिलता है। –

संबंधित मुद्दे

 संबंधित मुद्दे