2010-03-18 17 views
5

नामकरण मैं डिजाइन पैटर्न के बारे में और कोड के उदाहरण में मैं एक सम्मेलन जहां सार वर्ग एक विधि वाणी, उदाहरण के लिए देखा है सीख रहा हूँ:सार विधि हस्ताक्षर, विरासत, और "करो" सम्मेलन

public abstract class ServiceBase { 
... 

public virtual object GetSomething(); 

और फिर

protected abstract object DoGetSomething(); 

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

+0

क्या कुछ हो सकता है वर्चुअल होना चाहिए? – JaredPar

+0

हां यह निश्चित रूप से आभासी है। –

उत्तर

4

एक आम कारण अमूर्त विधि के आसपास मानक हैंडलिंग रखना है। उदाहरण के लिए, शायद अमूर्त विधि को केवल कुछ परिस्थितियों में ही बुलाया जा सकता है - कहें, splines के बाद reticulated किया गया है। उस स्थिति में, एक जगह में _areSplinesReticulated की जांच करना समझ में आता है - जनता को अपनी जांच करने के लिए अमूर्त विधि के प्रत्येक कार्यान्वयन की आवश्यकता के बजाय - Get Get कुछ विधि। या हो सकता है कि GetSomething 90% बॉयलरप्लेट है लेकिन कुछ अतिरिक्त तर्क या जानकारी का एक महत्वपूर्ण टुकड़ा आवश्यक है जो केवल कक्षाएं प्राप्त कर सकती हैं।

यह Template Method पैटर्न का एक रूप है।

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

0

मैं संस्करण आप पर लागू नहीं देखा है, जहां "GetSomething()" आभासी है, लेकिन मैंने देखा है (और लिखित) वर्ग इस तरह:

public abstract class Foo 
{ 
    protected abstract void DoBar(); 

    public void Bar() 
    { 
     // do stuff that has to happen regardless of how 
     // DoBar() has been implemented in the derived 
     // class 
     DoBar(); 
     // do other stuff 
    } 
} 

क्योंकि "बार" आभासी नहीं है (और मुझे लगता है कि आप इसे सुनिश्चित करने के लिए बस इसे सील भी कर सकते हैं) आपके पास "DoBar" विधि के पहले और बाद में कोड को "इंजेक्ट" करने का मौका है। यह काफी आसान है।

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