2017-06-23 51 views
6

मेरे पास TrendProviders का पदानुक्रम है जिसका उपयोग विभिन्न स्रोतों से डेटापॉइंट्स (रुझान) की श्रृंखला प्रदान करने के लिए किया जाता है।सी # पॉलिमॉर्फिज्म + जेनेरिक डिज़ाइन - सलाह की आवश्यकता

मैं सामान्य इंटरफेस के साथ शुरू कर दिया है:

इस प्रकार
public class TrendResult 
{ 
    public TrendResult() 
    { 
     Points = new Dictionary<DateTimeOffset, decimal>(); 
    } 

    public TrendResultCode Code { get; set; } 
    public string Name { get; set; } 
    public string Identifier { get; set; } 
    public Dictionary<DateTimeOffset, decimal> Points { get; set; } 
} 

TrendResultCode है के रूप में:

public enum TrendResultCode 
{ 
    OK, 
    DataParseError, 
    NoData, 
    UnknownError 
} 

public interface ITrendProvider<T> where T: TrendResult 
{ 
    IEnumerable<T> GetTrends(); 
} 

TrendResult प्राप्त प्रवृत्ति डेटा और ऑपरेशन स्थिति कोड के साथ एक परिणाम के वर्ग है

दो प्रकार (अभी तक) भी हैं अधिक विस्तृत इंटरफेस:

  • IFileTrendProvider - किसी भी फाइल से प्रवृत्तियों प्राप्त करने के लिए इस्तेमाल किया।

  • IServerTrendProvider - दूरस्थ सर्वर से प्रवृत्तियों प्राप्त करने के लिए, उदाहरण के लिए FTP का उपयोग करके इस्तेमाल किया।

IFileTrendProvider इस प्रकार है:

FileTrend प्रकार से एक:

public interface IServerTrendProvider : ITrendProvider<TrendResult> 
{ 
    IClient Client { get; set; } 
    Dictionary<string, string[]> RequestedServerTrendIDs { get; set; } 
} 

ठोस वर्ग कि इंटरफेस को लागू करता है इस प्रकार हैं:

public interface IFileTrendProvider : ITrendProvider<TrendResult> 
{ 
    IFileReader FileReader {get; set} 
    FileTrendDiscoveryPattern Pattern {get; set;} 
} 

IServerTrendProvider इस प्रकार है :

public class GenericFileTrendProvider : IFileTrendProvider<TrendResult> 
{ 
    public GenericFileTrendProvider() { } 

    public IFileReader FileReader {get; set} 
    public FileTrendDiscoveryPattern Pattern {get; set;} 

    public IEnumerable<TrendResult> GetTrends() 
    { 
     // Some code to obtain trends from file using FileReader 
    } 
} 

और ServerTrend प्रकार से एक:

public class ServerATrendProvider : IServerTrendProvider<TrendResult> 
{ 
    public ServerATrendProvider() { } 

    public IClient Client { get; set; } 
    public Dictionary<string, string[]> RequestedServerTrendIDs { get; set;} 

    public IEnumerable<TrendResult> GetTrends() 
    { 
     // Some code to obtain trends from remote server using Client 
    } 
} 

अब, मैं क्या हासिल करना चाहते हैं और जहां मैं आपकी मदद और सलाह की जरूरत:

IFileReader अपनी ही त्रुटि कोड का परिचय:

public enum FileReadResultCode 
{ 
    OK, 
    FileAlreadyOpen, 
    FileNotFound, 
    UnknownError 
} 

IClient इसके विशिष्ट ऑपरेशन त्रुटि कोड भी प्रस्तुत करता है:

public enum ClientCode 
{ 
    OK, 
    InvalidCredentials, 
    ResourceNotFounds, 
    UnknownError 
} 

दोनों के रूप में: IFileReader और IClient भी अपनी ही त्रुटि कोड देता है, कैसे मैं उन्हें TrendResult वस्तु GetTrends() विधि द्वारा लौटाए में intruduce सकता है, ताकि अंत में वहाँ के बारे में भी "आंतरिक" कुछ जानकारी हो जाएगा त्रुटि, न केवल TrendResult विशिष्ट त्रुटि?

मैं कुछ लचीला समाधान की आवश्यकता होगी - मैं TrendResult से इनहेरिट के बारे में सोच रहा था और एक FileTrendResult और ServerTrendResult ठोस प्रदाताओं में से प्रत्येक के लिए बनाते हैं, और इतना है कि वे अपने स्वयं के परिणाम प्रकार वापसी भी दोनों के लिए एक विशिष्ट त्रुटि enumerations को परिभाषित है, लेकिन कर सकते हैं यह किसी अन्य तरीके से किया जा सकता है?

+1

ग्रेट प्रश्न pitersmx। आम तौर पर हम यह सुनिश्चित करने के लिए पोस्ट में किसी भी बधाई या धन्यवाद नहीं जोड़ते हैं कि पोस्ट में जितना संभव हो उतना शोर है। मैंने आपके लिए धन्यवाद दिया है, बस आप जानते हैं। – Mafii

+1

अब मुझे कुछ महान उत्तर की आवश्यकता है :) – pitersmx

+0

विशिष्ट परिणाम एक 'TrendResult' पर लागू होते हैं या वे किसी स्रोत (उदा। फ़ाइल) से पढ़े जाने वाले सभी रुझान परिणामों के लिए समान होते हैं। उदाहरण के लिए, क्या 'जेनेरिकफाइलट्रेन्डप्रोवाइडर' ने कई फाइलें एक बार में पढ़ी हैं ताकि कुछ लौटे 'ट्रेंड रिसेट्स' में कोड 'फाइल नॉटफाउंड' हो सकता है जबकि अन्य के पास 'ओके' या कुछ अन्य कोड होगा? – Markus

उत्तर

3
इसके बजाय enumerations में संभावित त्रुटियों की एक पूर्व निर्धारित सूची होने के

(TrendResultCode, FileReadResultCode, ClientCode, ...) आप अपवाद की एक सूची संग्रहीत करने के लिए TrendResult वर्ग बदल सकते हैं और enumerations से छुटकारा मिल सकता है:

public class TrendResult 
{ 
    // ...  
    // public TrendResultCode Code { get; set; } 
    public IEnumerable<Exception> Errors { get; set; } 
    // ... 
} 

इस तरह, आप स्टैक ट्रेस और अन्य मूल्यवान जानकारी सहित त्रुटि की पूरी जानकारी संग्रहीत कर सकते हैं (या TrendResult में एक से अधिक समस्या होने पर कई त्रुटियों में से)। अप्रत्याशित त्रुटियों के लिए भी, आप एक अज्ञात त्रुटि के बजाय विवरण संग्रहीत करने में सक्षम हैं जो ट्रैक करना मुश्किल है।

यदि TrendResult में गणना में कोई आइटम नहीं है, तो इसमें कोई समस्या नहीं है। अन्यथा, आप जानकारी को लॉग में डाल सकते हैं।

कार्यान्वयन Open/Closed principle का पालन करता है, इसलिए आपको TrendResults को कार्यान्वित करने की आवश्यकता नहीं है जो त्रुटि की ओर ले जाने वाली नई स्थितियां हैं।

आपके व्यावसायिक अपवादों के लिए, उदा। पार्सिंग त्रुटियों, आपको विशिष्ट अपवाद प्रकार बनाना चाहिए ताकि आप बाद में इन त्रुटियों का विश्लेषण अपने प्रकार के आधार पर कर सकें।

+0

धन्यवाद, मैं कोशिश करूँगा। मैं आपके समाधान को बहुत पसंद करना शुरू कर रहा हूं। मुझे लगता है कि यह मेरे लिए जाने का सही तरीका है। एक बार फिर धन्यवाद! – pitersmx

1

के बाद से IServerTrendProvider अन्य कंप्यूटरों से TrendResults प्राप्त होगा, आप सामान्य मामले में System.Exception उपयोग करने में सक्षम नहीं होगा।

इन परिस्थितियों में, लोग तारों पर वापस आते हैं - जो हमेशा ऑपरेटिंग सिस्टम पर ध्यान दिए बिना समर्थित होते हैं। जब स्रोत-कोड के टुकड़े (जैसे नाम, स्टैक ट्रेस) त्रुटि संदेश में भेजने, क्योंकि इन हैकर्स के लिए काम का हो सकता है

public class TrendResult 
{ 
    public string[] ErrorMessages; // Error messages - could be the stack trace 
    public int[] ErrorCodes;  // Os-specific error numbers 
} 

सुरक्षा पर विचार करें।

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