निर्भरता इंजेक्शन का उपयोग करते समय मैं अपने इंटरफेस और कंक्रीट कक्षाओं के बीच 1-से-1 संबंध रखने का दोषी पाया गया हूं। जब मुझे किसी इंटरफ़ेस में कोई विधि जोड़ने की आवश्यकता होती है, तो मैं इंटरफ़ेस को लागू करने वाले सभी वर्गों को तोड़ देता हूं।इंटरफेस या कक्षाओं के साथ निर्भरता इंजेक्शन
यह एक साधारण उदाहरण है, लेकिन मान लीजिए कि मुझे ILogger
को मेरी कक्षाओं में से एक में इंजेक्ट करने की आवश्यकता है।
public interface ILogger
{
void Info(string message);
}
public class Logger : ILogger
{
public void Info(string message) { }
}
इस तरह के 1 से 1 रिश्ते को कोड गंध की तरह लगता है। चूंकि मेरे पास केवल एक ही कार्यान्वयन है, यदि कोई कक्षा बनाते हैं और Info
विधि को केवल एक वर्ग के लिए इंटरफ़ेस बनाने के बजाय मेरे परीक्षणों में ओवरराइड करने के लिए आभासी के रूप में चिह्नित करने के लिए कोई संभावित समस्याएं हैं?
public class SqlLogger : Logger
{
public override void Info(string message)
{
// Log to SQL
}
}
इन कक्षाओं में से प्रत्येक के विशिष्ट गुण या तरीकों कि एक टपकाया अमूर्त बनाने चाहते हैं, तो मैं एक आधार बाहर निकाल सकते:
public class Logger
{
public virtual void Info(string message)
{
// Log to file
}
}
अगर मैं एक और क्रियान्वयन की आवश्यकता नहीं है, मैं Info
विधि ओवरराइड कर सकते हैं कक्षा:
public class Logger
{
public virtual void Info(string message)
{
throw new NotImplementedException();
}
}
public class SqlLogger : Logger
{
public override void Info(string message) { }
}
public class FileLogger : Logger
{
public override void Info(string message) { }
}
कारण मैंने आधार वर्ग को सार के रूप में चिह्नित नहीं किया है क्योंकि अगर मैं कभी भी एक और विधि जोड़ना चाहता हूं, तो मैं exis तोड़ नहीं पाऊंगा टिंग कार्यान्वयन। उदाहरण के लिए, यदि मेरे FileLogger
को Debug
विधि की आवश्यकता है, तो मैं मौजूदा SqlLogger
को तोड़ने के बिना बेस क्लास Logger
अपडेट कर सकता हूं।
public class Logger
{
public virtual void Info(string message)
{
throw new NotImplementedException();
}
public virtual void Debug(string message)
{
throw new NotImplementedException();
}
}
public class SqlLogger : Logger
{
public override void Info(string message) { }
}
public class FileLogger : Logger
{
public override void Info(string message) { }
public override void Debug(string message) { }
}
फिर, यह एक साधारण उदाहरण है, लेकिन जब मुझे एक इंटरफ़ेस पसंद करना चाहिए?
_ कारण मैंने आधार वर्ग को सार के रूप में चिह्नित नहीं किया है क्योंकि अगर मैं कभी भी एक और विधि जोड़ना चाहता हूं, तो एक अमूर्त वर्ग में कार्यान्वयन हो सकता है। आप अपने सार लॉगर वर्ग में डीबग विधि जोड़ सकते हैं। –
मौजूदा कार्यान्वयन तोड़ना केवल एक समस्या है यदि आप पुन: प्रयोज्य लाइब्रेरी लिख रहे हैं। क्या आप? या आप बस व्यवसाय आवेदन की एक पंक्ति लिख रहे हैं? – Steven
यह सवाल का दायरा नहीं है, लेकिन विरासत अतिरंजित है। एक 'SqlLogger'' SqlLogPersistenceStrategy' के साथ बस एक ठोस 'लॉगर' है। ज्यादातर मामलों में संरचना विरासत से काफी बेहतर है। आपकी समस्या के लिए, आईएसपी के बारे में क्या? 'ILogInfo',' ILogError', आदि – plalx