2008-11-13 16 views
6

मैं एक अपाचे access.log फ़ाइल को एक निश्चित तरीके से एक पायथन प्रोग्राम के साथ पार्स करना चाहता हूं, और हालांकि मैं ऑब्जेक्ट उन्मुख प्रोग्रामिंग के लिए पूरी तरह से नया हूं, मैं अब इसे करना शुरू करना चाहता हूं।क्या अंतर्निहित कक्षाओं से उत्तराधिकारी के लिए यह सही है?

मैं एक वर्ग बनाने के लिए जा रहा हूँ ApacheAccessLog, और केवल एक चीज मैं अब कल्पना कर सकते हैं, यह कर रही होगी 'ReadLine' तरीका है। क्या यह इस मामले में बिल्टिन फ़ाइल कक्षा से उत्तराधिकारी के लिए पारंपरिक रूप से सही है, इसलिए कक्षा फ़ाइल फ़ाइल के उदाहरण की तरह ही व्यवहार करेगी, या नहीं? ऐसा करने का सबसे अच्छा तरीका क्या है?

उत्तर

15

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

इस के लिए कम से कम दो कारण हैं:

  1. प्रतिनिधिमंडल फ़ाइल के स्थान पर आप किसी भी अन्य वस्तु को लागू करने वाली एक readline विधि (बतख टाइपिंग यहाँ काम आता है) का उपयोग कर सकते वस्तुओं में उदाहरण के लिए, युग्मन कम कर देता है ।
  2. फ़ाइल से विरासत में जब आपकी कक्षा का सार्वजनिक इंटरफ़ेस अनावश्यक रूप से व्यापक हो जाता है। इसमें फ़ाइल पर परिभाषित सभी विधियां शामिल हैं, भले ही ये विधियां अपाचे लॉग के मामले में समझ में न हों।
1

यह एक निर्मित कक्षा से प्राप्त करने के लिए पूरी तरह से स्वीकार्य है। इस मामले में मैं कहूंगा कि आप पैसे पर सही हैं।
लॉग "एक है" फ़ाइल है जो आपको बताती है कि विरासत ठीक है ..

सामान्य नियम।
कुत्ता "एक जानवर है, इसलिए पशु से प्राप्त होता है।
मालिक "एक" एन जानवर है इसलिए पशु से प्राप्त नहीं होता है।

1

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

1

आपको "बिल्टिन" कक्षा से काफी सुरक्षित विरासत होना चाहिए, क्योंकि बाद में इन कक्षाओं में संशोधन वर्तमान संस्करण के साथ संगत होंगे।

हालांकि, आपको गीलेर के बारे में गंभीरता से सोचना चाहिए, आप वास्तव में बिल्टिन क्लास द्वारा प्रदान की गई अतिरिक्त कार्यक्षमता में अपनी कक्षा को जोड़ना चाहते हैं। जैसा कि किसी अन्य उत्तर में बताया गया है, आपको इसके बजाय प्रतिनिधिमंडल का उपयोग करके (शायद यहां तक ​​कि पसंद करना चाहिए) पर विचार करना चाहिए।

विरासत से बचने के उदाहरण के रूप में यदि आपको इसकी आवश्यकता नहीं है तो आप java.util.Stack कक्षा देख सकते हैं। चूंकि यह वेक्टर को बढ़ाता है, यह वेक्टर पर विधियों के सभी प्राप्त करता है। इनमें से अधिकतर तरीके स्टैक द्वारा निहित अनुबंध को तोड़ते हैं, उदा। LIFO। यह एक वेक्टर का आंतरिक रूप से उपयोग करके स्टैक को कार्यान्वित करने के लिए बहुत बेहतर होता, केवल एपीआई के रूप में स्टैक विधियों को उजागर करता था।इसके बाद एरेलेलिस्ट या कुछ और बाद में कार्यान्वयन को बदलना आसान हो गया था, अब विरासत के कारण इनमें से कोई भी संभव नहीं है।

6

मैं जावा पृष्ठभूमि से आ रहा हूं लेकिन मुझे पूरा विश्वास है कि एक ही सिद्धांत पायथन में लागू होगा। अंगूठे के नियम के रूप में आपको कभी किसी वर्ग से प्राप्त नहीं होना चाहिए जिसका कार्यान्वयन आप समझ में नहीं आता है और तब तक नियंत्रित नहीं करता जब तक वह वर्ग विशेष रूप से विरासत के लिए डिज़ाइन नहीं किया गया हो। यदि इसे इस तरह से डिजाइन किया गया है तो इसे इसके दस्तावेज़ीकरण में स्पष्ट रूप से वर्णन करना चाहिए।

इसका कारण यह है कि विरासत संभावित रूप से उस वर्ग के कार्यान्वयन विवरण से आपको बाध्य कर सकती है जिसे आप विरासत में प्राप्त कर रहे हैं।

जोश बलोच की किताब से एक उदाहरण का उपयोग करने के लिए 'प्रभावी जावा'

हम क्रम में वर्ग ArrayList वर्ग का विस्तार करने के लिए आइटम है कि अपने जीवन समय के दौरान यह करने के लिए जोड़ा गया था की संख्या की गणना करने में सक्षम हो तो (जरूरी नहीं कि वर्तमान में इसमें मौजूद संख्या) हम इस तरह कुछ लिखने के लिए लुभाने वाले हो सकते हैं।

public class CountingList extends ArrayList { 
    int counter = 0; 

    public void add(Object o) { 
     counter++; 
     super.add(0); 
    } 

    public void addAll(Collection c) { 
     count += c.size(); 
     super.addAll(c); 
    } 

    // Etc. 
} 

अब यह एक्सटेंशन ऐसा लगता है कि यह सूची में जोड़े गए तत्वों की संख्या को सटीक रूप से गिनता है लेकिन वास्तव में ऐसा नहीं हो सकता है। यदि ArrayList ने addAll को Collection पर प्रदान करके लागू किया है और प्रत्येक तत्व के लिए अपनी इंटरफ़ेस विधि addAll पर कॉल किया है तो हम addAll विधि के माध्यम से जोड़े गए प्रत्येक तत्व को गिनेंगे। अब हमारी कक्षा का व्यवहार ArrayList के कार्यान्वयन विवरण पर निर्भर है।

यह List के अन्य कार्यान्वयनों को हमारे CountingList कक्षा के साथ उपयोग करने में सक्षम नहीं होने के नुकसान के अतिरिक्त है। इसके अलावा ऊपर चर्चा की गई एक ठोस वर्ग से विरासत के नुकसान।

यह मेरी समझ है कि पायथन जावा के समान (यदि समान नहीं है) विधि प्रेषण तंत्र का उपयोग करता है और इसलिए उसी सीमाओं के अधीन होगा। अगर कोई पाइथन में एक उदाहरण प्रदान कर सकता है तो मुझे यकीन है कि यह और भी उपयोगी होगा।

0

आपको ऐसा लगता है कि इस मामले में प्रतिनिधिमंडल बेहतर रणनीति है। फिर भी, मैं इसे जोड़ना चाहता हूं, प्रतिनिधिमंडल को छोड़कर, अंतर्निहित कक्षा को विस्तारित करने में कुछ भी गलत नहीं है, विशेष रूप से यदि आपका विकल्प, भाषा के आधार पर, "बंदर पैचिंग" है (http://en.wikipedia.org/wiki/Monkey_patch देखें)

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