[英]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
}
作為兩者: IFileReader
和IClient
也返回自己的錯誤代碼,我如何在GetTrends()
方法返回的TrendResult
對象中TrendResult
它們,這樣最終還會有一些關於“內部”錯誤的信息,而不僅僅是TrendResult
具體錯誤?
我需要一些靈活的解決方案-我在想繼承TrendResult
並創建一個FileTrendResult
和ServerTrendResult
每個混凝土供應商,同時也定義了兩種特定的錯誤枚舉,使他們返回自己的結果類型,但它可以在完成其他一些方式?
您可以更改TrendResult
類以存儲異常列表並刪除枚舉,而不是在枚舉中有預定義的可能錯誤列表( TrendResultCode
, FileReadResultCode
, ClientCode
,...):
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.