मेरे पास ढीले युग्मन और इंटरफेस के बारे में एक वैचारिक/सैद्धांतिक प्रश्न है।
तो एक इंटरफ़ेस का उपयोग करने का एक तरीका एक निश्चित कन्स्ट्रक्टर द्वारा आवश्यक पैरामीटर को समाहित करना हो सकता है:
class Foo
{
public Foo(IFooInterface foo)
{
// do stuff that depends on the members of IFooInterface
}
}
तो जब तक वस्तु अनुबंध को लागू करती है, तब तक सब कुछ काम करेगा। मेरी समझ से यहां मुख्य लाभ यह है कि यह बहुरूपता को सक्षम बनाता है, लेकिन मुझे यकीन नहीं है कि इसका वास्तव में ढीले युग्मन से कोई लेना-देना है या नहीं।
आइए तर्क के लिए कहें कि एक IFooInterface इस प्रकार है:
interface IFooInterface
{
string FooString { get; set; }
int FooInt { get; set; }
void DoFoo(string _str);
}
एक ढीले युग्मन दृष्टिकोण से, उपरोक्त कन्स्ट्रक्टर में IFooInterface का उपयोग न करना बेहतर नहीं होगा, और इसके बजाय फू को इस तरह सेट अप करें:
class Foo
{
public Foo(string _fooString, int _fooInt, Action<string> _doFoo)
{
// do the same operations
}
}
क्योंकि कहें कि मैं फू की कार्यक्षमता को किसी अन्य प्रोजेक्ट में छोड़ना चाहता हूं। इसका मतलब है कि अन्य प्रोजेक्ट को भी IFooInterface को संदर्भित करना होगा, एक और निर्भरता जोड़ना। लेकिन इस तरह मैं फू को किसी अन्य प्रोजेक्ट में छोड़ सकता हूं और यह वही व्यक्त करता है जो इसे काम करने के लिए आवश्यक है। जाहिर है, मैं सिर्फ ओवरलोडेड कंस्ट्रक्टर्स का उपयोग कर सकता हूं, लेकिन तर्क के लिए कह सकता हूं कि मैं फू के कंस्ट्रक्टर्स को संशोधित नहीं करना चाहता और/या नहीं कर सकता।
सबसे महत्वपूर्ण पहलू (मेरे लिए कम से कम) यह है कि यदि आपके पास आदिम मापदंडों के एक समूह के साथ एक विधि है तो यह बदसूरत और पढ़ने में कठिन हो जाता है। तो मेरे पास एक प्रकार का रैपिंग फ़ंक्शन बनाने का विचार था जो आपको अभी भी सभी आदिम प्रकारों के बजाय इंटरफ़ेस में पास करने की अनुमति देता है:
public static Func<T, R> Wrap<T, R>(Func<T, object[]> conversion)
{
return new Func<T, R>(t =>
{
object[] parameters = conversion(t);
Type[] args = new Type[parameters.Length];
for (int i = 0; i < parameters.Length; i++)
{
args[i] = parameters[i].GetType();
}
ConstructorInfo info = typeof(R).GetConstructor(args);
return (R)info.Invoke(parameters);
});
}
यहां विचार यह है कि मैं एक ऐसा फ़ंक्शन वापस प्राप्त कर सकता हूं जो कुछ इंटरफ़ेस का उदाहरण लेता है जो फू की आवश्यकताओं के अनुरूप है, लेकिन फू सचमुच उस इंटरफ़ेस के बारे में कुछ भी नहीं जानता है। इसे इस तरह इस्तेमाल किया जा सकता है:
public Foo MakeFoo(IFooInterface foo)
{
return Wrap<IFooInterface, Foo>(f =>
new object[] { f.FooString, f.FooInt, f.DoFoo })(foo);
}
मैंने इस बारे में चर्चा सुनी है कि इंटरफेस को ढीले-युग्मन को सक्षम करने के लिए कैसे माना जाता है, लेकिन इस बारे में सोच रहा था।
आश्चर्य है कि कुछ अनुभवी प्रोग्रामर क्या सोचते हैं।
2 जवाब
मेरा पहला विचार यह है कि आपने क्रमशः FooString
और FooInt
के सेटर्स के लिए Action<string>
और Action<int>
प्रदान नहीं किया। IFooInterface
के कार्यान्वयन में उन सेटर्स से संबंधित नियम हो सकते हैं, और इंटरफ़ेस पर उजागर नहीं किए गए अन्य कार्यान्वयन विवरणों तक पहुंच की आवश्यकता हो सकती है।
उसी तरह, आपको एक Func<string>
और Func<int>
को भी स्वीकार करना चाहिए: IFooInterface
के कार्यान्वयन में इस बारे में नियम हो सकते हैं कि FooString
और FooInt
समय के अनुसार क्या हैं आगे बढ़ता है। उदाहरण के लिए, DoFoo
उन मानों की पुनर्गणना कर सकता है; आप यह नहीं मान सकते हैं कि वे केवल उन क्षेत्रों के लिए पास-थ्रू हैं जो कभी नहीं बदलते हैं।
इसे और आगे ले जाते हुए, यदि गेटर्स, सेटर्स, या DoFoo
को सामान्य स्थिति तक पहुंच की आवश्यकता होती है, तो जब आप उन्हें बनाते हैं तो फ़ंक्शन और क्रियाओं को चर के एक ही सेट पर बंद करने की आवश्यकता होगी। उस समय, आप परिवर्तनशील जीवन काल और प्रतिनिधियों के बीच संबंधों को समझने के लिए कुछ मानसिक जिम्नास्टिक कर रहे होंगे।
राज्य और व्यवहार की यह जोड़ी ठीक वही है जो एक वर्ग व्यक्त करता है, और कार्यान्वयन विवरण छिपाना ठीक वही है जो एक इंटरफ़ेस प्रदान करता है। उन अवधारणाओं को उनके घटक तत्वों में तोड़ना निश्चित रूप से प्राप्त करने योग्य है, लेकिन यह सदस्यों को एक प्रकार से समूहित करके प्राप्त सुसंगतता को भी तोड़ देता है।
इसे दूसरे तरीके से रखने के लिए, आप मुझे नूडल्स, सॉस, सब्जियां और हैमबर्गर दे सकते हैं, लेकिन यह स्पेगेटी और मीटबॉल नहीं है :-)
अपने प्रारंभिक उदाहरण में आप पैरामीटर ऑब्जेक्ट पैटर्न के काफी करीब हैं, हालांकि इसका उपयोग करना अधिक सामान्य है एक इंटरफ़ेस के अतिरिक्त अमूर्त के बिना यहां एक साधारण वर्ग (अक्सर ऑटो-गुणों के साथ)।
आमतौर पर जब आप एक कंस्ट्रक्टर में एक इंटरफ़ेस पास करने के बारे में सुनते हैं, तो यह प्राइमेटिव को बदलने के लिए नहीं बल्कि निर्भरता इंजेक्शन के रूप में होता है। सीधे MyFooRepository
पर निर्भर होने के बजाय, कोई IFooRepository
पर निर्भरता लेगा जो एक विशिष्ट कार्यान्वयन के लिए युग्मन को हटा देगा।
संबंधित सवाल
नए सवाल
c#
C # (उच्चारण "तेज देखें") Microsoft द्वारा विकसित एक उच्च स्तरीय, सांख्यिकीय रूप से टाइप किया हुआ, बहु-प्रतिमान प्रोग्रामिंग भाषा है। C # कोड आमतौर पर Microsoft के .NET परिवार के टूल और रन-टाइम को लक्षित करता है, जिसमें .NET फ्रेमवर्क, .NET कोर और Xamarin अन्य शामिल हैं। C # या C # के औपचारिक विनिर्देश में लिखे गए कोड के बारे में प्रश्नों के लिए इस टैग का उपयोग करें।