2010-02-25 14 views
11

के साथ फ्लाईवेट और फैक्टरी समस्या मुझे मानसिक रूप से एक फ्लाईवेट पैटर्न दुविधा में फंस गया प्रतीत होता है।IDISposable

सबसे पहले, चलो कहते हैं कि मैं एक डिस्पोजेबल प्रकार DisposableFiddle और एक कारखाने FiddleFactory डालते हैं:

public interface DisposableFiddle : IDisposable 
{ 
    // Implements IDisposable 
} 

public class FiddleFactory 
{ 
    public DisposableFiddle CreateFiddle(SomethingThatDifferentiatesFiddles s) 
    { 
     // returns a newly created fiddle. 
    } 
} 

फिर, मेरी राय में, यह FiddleFactory के ग्राहक के लिए काफी स्पष्ट है कि कारखाना बनाया बेला के अधिकार का दावा नहीं और यह कि क्लाइंट की जिम्मेदारी है जब वह इसके साथ किए गए पहेली को निपटाने का अधिकार रखता है।

public class FiddleFactory 
{ 
    private Dictionary<SomethingThatDifferentiatesFiddles, DisposableFiddle> fiddles = new ...;   

    public DisposableFiddle CreateFiddle(SomethingThatDifferentiatesFiddles s) 
    { 
     // returns an existing fiddle if a corresponding s is found, 
     // or a newly created fiddle, after adding it to the dictionary, 
     // if no corresponding s is found. 
    } 
} 

तब मैं नैतिक रूप से ही डिस्पोजेबल कारखाना बनाने के लिए बाध्य लग रहा है, के बाद से यह fiddles बनाता है और संदर्भ रखता है:

हालांकि, के बजाय कहना है कि मैं फ्लायवेट पैटर्न का उपयोग करके ग्राहकों के बीच fiddles साझा करना चाहते हैं चलो उनके जीवनकाल के दौरान उनके लिए। लेकिन इससे ग्राहकों को समस्याएं आती हैं जो मानते हैं कि उनके पास झुकाव है और इसलिए उन्हें निपटाना चाहिए।

वास्तव में समस्या है कि मैं कारखाने FiddleFactory बजाय, कहते हैं, FiddlePool कहते हैं, और "रचना" विधि CreateFiddle बजाय GetFiddle? इस तरह:

public class FiddlePool : IDisposable 
{ 
    private Dictionary<SomethingThatDifferentiatesFiddles, DisposableFiddle> fiddles = new ...;   

    public DisposableFiddle GetFiddle(SomethingThatDifferentiatesFiddles s) 
    { 
     // returns an existing fiddle if a corresponding s is found, 
     // or a newly created fiddle, after adding it to the dictionary, 
     // if no corresponding s is found. 
    } 

    // Implements IDisposable 
} 

तो यह ग्राहक के लिए स्पष्ट है कि यह वापस आ बेला ही नहीं होगी और यह fiddles निपटान के लिए पूल की जिम्मेदारी है।

या क्या यह केवल आसानी से दस्तावेज़ीकरण के हल हो सकता है?

क्या दुविधा से कोई रास्ता है? क्या कोई दुविधा भी है? :-)

उत्तर

7

मैं इस समस्या से बाहर दो तरीके देख सकते हैं:

  • ThreadPool शैली: कक्षाएं नया स्वरूप इतना FiddlePool बारीकियों काम करने के लिए एक इंटरफेस प्रदान करता है। पूल Fiddle उदाहरणों को नहीं सौंपता है क्योंकि इसकी बजाय FiddlePool.PlayFiddle विधि है। चूंकि पूल खराब जीवनकाल को नियंत्रित करता है, इसलिए यह उनका निपटान करने के लिए ज़िम्मेदार है।

  • SqlConnection शैली: इतना है कि यह वास्तव में सिर्फ बेला पूल (जो बेला वर्ग समाहित) को fiddles रिटर्न Fiddle के सार्वजनिक निपटाने विधि को संशोधित। आंतरिक रूप से, फिल्ड पूल वास्तव में डिस्पोजेबल संसाधनों को जारी करने का ख्याल रखता है।

+0

धन्यवाद, पहला व्यक्ति डेमेटर के कानून का बेहतर अनुसरण करता है और दूसरा मेरे समग्र डिजाइन में बेहतर फिट बैठता है। हमम ... –

+0

मैं अपने दो सेंट को पहले दृष्टिकोण के लिए रखूंगा - मैंने देखा है कि बहुत से लोग अपने स्वयं के एसक्यूएल कनेक्शन पूल लिखने की कोशिश करते हैं! (वास्तव में नहीं, लेकिन मुझे * यह समझाना पड़ा कि यह जरूरी क्यों नहीं है।) –

2

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

+3

मेरे विचार बिल्कुल। इसके अतिरिक्त, मैं संभवतया आपकी कक्षा डिस्पोजेबलफिल्ड को कॉल नहीं करूँगा जबतक कि आप उपयोगकर्ता को निपटान नहीं करना चाहते हैं() इसे ... –

+0

@Reed: डिस्पोजेबलफ़िल्ड के बारे में सहमति हुई। इरादा व्यक्त करने के लिए उचित नामकरण महत्वपूर्ण है, और गलत उपयोग के खिलाफ रक्षा की पहली पंक्ति है। – jrista

+0

हे, हाँ, मैंने बस अपने (भ्रमित) चरणों में पालन करना आसान बनाने के लिए उदाहरण के नाम पर डिस्पोजेबल प्रस्तुत किया है ... –

1

ग्राहकों को बताने के लिए ग्राहकों को बताने के लिए आपको केवल दस्तावेज़ीकरण और नामकरण विधियों से कुछ और करना चाहिए। वास्तव में ग्राहकों को निपटान करना बेहतर होगा ताकि उपयोग पैटर्न बना सकें। हमारे डेटाबेस कनेक्शन पूल से कुछ दिशा लें।

डेटाबेस पूल कनेक्शन को एक समूह बनाता है जो स्वयं पूल-जागरूक हैं।कॉलिंग कोड एक कनेक्शन बनाता है, इसे खोलता है, और उस पर करीब (निपटान) कॉल करता है। कॉलिंग कोड को वास्तव में यह भी पता नहीं है कि यह पूल किया गया है या नहीं, यह सभी कनेक्शन क्लास द्वारा आंतरिक रूप से संभाला जाता है। पूल किए गए कनेक्शन के साथ, यदि कनेक्शन पहले से खुला है तो ओपन() को कॉल करना अनदेखा कर दिया जाता है। बंद करें()/निपटान() को बुलाया जाता है और पूल किए गए कनेक्शन के मामले में यह वास्तव में कनेक्शन को बंद करने के बजाय पूल पर वापस लौटाता है।

आप पूलेडफिल्ड क्लास बनाकर वही काम कर सकते हैं जो ओवरराइड को ओवरराइड करता है और ऑब्जेक्ट को पूल में लौटाता है। आदर्श रूप से ग्राहक को यह भी पता नहीं होना चाहिए कि यह एक पूल फीड है।

+0

"आदर्श रूप से ग्राहक को यह भी पता नहीं होना चाहिए कि यह पूल वाला फीड है।" - हाँ, मैं उस पर सहमत हूं। मुझे लगता है कि यह एक कार्यान्वयन विस्तार है जो छुपा हुआ बेहतर है। –

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