2013-10-08 3 views
16

मैंने पहली बार एक सहकर्मी को ऐसा किया जब उसने ऑब्जेक्ट पूल लागू किए। उन्होंने कक्षा को पारित किया जो कि सामान्य आधार वर्ग के पैरामीटर के रूप में पूल किया जा रहा था। इस बेस क्लास ने पूलिंग कोड डाला।क्या एक वर्ग को सामान्य आधार वर्ग बुराई के पैरामीटर के रूप में खुद को पास करना है?

अजीब चीज यह है कि बेस क्लास अपने बच्चों के बारे में जान जाएगी। यह हर सामान्य मामले में बुरा अभ्यास माना जाता है। लेकिन इस मामले में माता-पिता दोहराव कोड लिखने से बचने के लिए सिर्फ एक तकनीकी समाधान है। किसी भी अन्य कोड द्वारा बेस क्लास का संदर्भ कभी नहीं दिया जाता है।

इस निर्माण के साथ एक दोष यह है कि यह "बेस क्लास जलता है"। आप पदानुक्रम के बीच में जेनेरिक बेस क्लास पेश नहीं कर सकते हैं। यह समस्या विषय के बाहर हो सकती है।

public abstract class Singleton<T> where T : class 
{ 
    public static T Instance { get; private set; } 

    public Singleton() 
    { 
     if (Instance != null) 
      throw new Exception("Singleton instance already created."); 
     Instance = (T) (object) this; 
    } 
} 

public class MyClass : Singleton<MyClass> 
{ 
} 

बेहतर कोड:

नीचे एक विचारणीय उदाहरण है

public abstract class Singleton<T> where T : Singleton<T> 
{ 
    public static T Instance { get; private set; } 

    public Singleton() 
    { 
     if (Instance != null) 
      throw new Exception("Singleton instance already created."); 
     Instance = (T) this; 
    } 
} 

public class MyClass : Singleton<MyClass> 
{ 
} 

उत्तर

14

नहीं; यह CRTP नामक एक प्रसिद्ध पैटर्न है।
यह विशेष रूप से वर्चुअल विधियों के विकल्प के रूप में सी ++ में उपयोगी है।

आप इसे IComparable<T> और IEquatable<T> में नेट फ्रेमवर्क के अंदर देख सकते हैं।

जोड़ा मजबूती के लिए, आप where T : Singleton<T>

+0

आप उस अंतिम वाक्य के साथ अपना मन उड़ा रहे हैं। कक्षा सिंगलटॉन जहां टी: सिंगलटन ? क्या आपको अंतहीन रिकर्सिव जाने की आवश्यकता नहीं होगी (प्रत्येक टी को सिंगलटन होना होगा, जहां वह टी फिर से सिंगलटन इत्यादि) – Kristof

+0

जोड़ा गया स्लैक्स कोड सुधार। पहली पंक्ति आपके सिर स्पिन बनाती है। –

+0

@ क्रिस्टोफ उदाहरण देखें: 'सार्वजनिक MyClass: सिंगलटन 'ऊपर।प्रकार, 'MyClass' IS-A' सिंगलटन 'इसलिए यह काम करता है। यद्यपि यह अभी भी थोड़ा मस्तिष्क-गंदा है। –

3

SLaks जोड़ना चाहिए सही है - यह है जब आप अपने आधार वर्ग जो दृढ़ता से अपने व्युत्पन्न वर्ग के लिए लिखा गया में कोड प्रदान करना चाहते हैं के लिए एक उपयोगी पैटर्न है, आम तौर पर।

आप आम तौर पर जेनेरिक पैरामीटर को सामान्य प्रकार से प्राप्त करने के लिए जेनेरिक पैरामीटर में एक प्रकार की बाधा जोड़ते हैं। इस बाधा को जोड़ने के लिए वाक्यविन्यास रिकर्सिव दिखता है, लेकिन इसके बारे में घबराओ मत - इसका मूल्यांकन निरंतर मूल्यांकन नहीं किया जाता है और यह सुनिश्चित करता है कि केवल वैध जेनेरिक प्रकार ही कक्षाएं प्राप्त हों।

उदाहरण के लिए, मान लीजिए कि आप एक चाय और कॉफी मिश्रण व्यवसाय चलाते हैं। कॉफी के साथ कॉफी और चाय के साथ चाय मिश्रण करने के लिए यह समझ में आता है, लेकिन आप यह सुनिश्चित करना चाहते हैं कि आप चाय के साथ कॉफी मिश्रण नहीं कर सकते। हालांकि, चूंकि वे दोनों पेय पदार्थ हैं, इसलिए आप उन्हें उसी तरह मॉडल करना चाहते हैं।

public abstract class Beverage<T> where T : Beverage<T> 
{ 
    public abstract T Blend(T drink1, T drink2); 
} 

public class Tea : Beverage<Tea> 
{ 
    public override Tea Blend(Tea drink1, Tea drink2) 
    { 
     // Blend tea here. 
    } 
} 
public class Coffee : Beverage<Coffee> 
{ 
    public override Coffee Blend(Coffee drink1, Coffee drink2) 
    { 
     // Blend coffee here. Although coffee is nasty, so 
     // why you'd want to is beyond me. 
    } 
} 

जब CRTP बारे में पढ़ने, यह याद है कि सी ++ टेम्पलेट्स केवल अल्पज्ञता सी # जेनरिक के समान हैं लायक है। मुख्य अंतर यह है कि टेम्पलेट्स प्रभावी रूप से कोड जनरेशन टूल होते हैं जो संकलन-समय पर काम करते हैं, जबकि सी # जेनेरिक रन टाइम पर समर्थित होते हैं।

इसके अलावा, इस तरह के कोड लिखने से पठनीयता कम हो सकती है। इसलिए यद्यपि निश्चित रूप से ऐसे उदाहरण हैं जहां यह सही दृष्टिकोण होगा, आपको उस समस्या के बारे में सोचना चाहिए जिसे आप हल करने की कोशिश कर रहे हैं और देखें कि क्या कोई और सरल दृष्टिकोण है या नहीं।

+0

MyClass.Instance संकलित करता है। –

+0

उचित रूप से संपादित किया गया है। –

+2

बेशक, 'पब्लिक क्लास कॉफी: पेय ' कानूनी घोषणा है। इसे गड़बड़ करना आसान है। – Brian

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

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