簡體   English   中英

c#polymorphism +泛型設計 - 需要建議

[英]c# polymorphism + generics design - advice needed

我有一個TrendProviders層次結構,用於提供來自不同來源的一系列數據點(趨勢)。

我已經開始使用通用接口:

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

TrendResult是一個結果類,包含獲得的趨勢數據和操作狀態代碼:

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
}

還有兩種類型(到目前為止)更詳細的接口:

  • IFileTrendProvider - 用於從任何文件獲取趨勢。

  • IServerTrendProvider - 用於從遠程服務器獲取趨勢,例如使用FTP。

IFileTrendProvider是這樣的:

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

IServerTrendProvider是這樣的:

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

實現接口的具體類如下:

FileTrend類型之一:

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
}

作為兩者: IFileReaderIClient也返回自己的錯誤代碼,我如何在GetTrends()方法返回的TrendResult對象中TrendResult它們,這樣最終還會有一些關於“內部”錯誤的信息,而不僅僅是TrendResult具體錯誤?

我需要一些靈活的解決方案-我在想繼承TrendResult並創建一個FileTrendResultServerTrendResult每個混凝土供應商,同時也定義了兩種特定的錯誤枚舉,使他們返回自己的結果類型,但它可以在完成其他一些方式?

您可以更改TrendResult類以存儲異常列表並刪除枚舉,而不是在枚舉中有預定義的可能錯誤列表( TrendResultCodeFileReadResultCodeClientCode ,...):

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

這樣,您可以存儲錯誤的完整信息,包括堆棧跟蹤和其他有價值的信息(如果單個TrendResult存在多個問題,則可以存儲多個錯誤)。 即使出現意外錯誤,您也可以存儲詳細信息,而不是存在難以追蹤的未知錯誤。

如果TrendResult在枚舉中沒有任何項目,則它沒有任何問題。 否則,您可以將信息放入日志中。

實現遵循開放/封閉原則 ,因此如果存在導致錯誤的新條件,則不必更改處理TrendResults的實現。

對於業務異常,例如解析錯誤,您應該創建特定的異常類型,以便以后可以根據類型分析這些錯誤。

由於IServerTrendProvider將從其他計算機接收TrendResults,因此在一般情況下您將無法使用System.Exception

在這些情況下,人們會回歸到字符串 - 無論操作系統如何,它們都會得到支持。

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

在錯誤消息中發送源代碼片段(例如名稱,堆棧跟蹤)時考慮安全性,因為這些可能對黑客有用。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM