c# полиморфизм + дженерики дизайн-советы, необходимые
у меня есть иерархия 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
также возвращает свои собственные коды ошибок, как я мог бы ввести их в
2 ответов
вместо того, чтобы иметь заранее определенный список возможных ошибок в нумерации (TrendResultCode
, FileReadResultCode
, ClientCode
, ...) вы можете изменить TrendResult
класс для хранения списка исключений и избавиться от перечислений:
public class TrendResult
{
// ...
// public TrendResultCode Code { get; set; }
public IEnumerable<Exception> Errors { get; set; }
// ...
}
таким образом, вы можете сохранить полную информацию об ошибке, включая трассировку стека и другую ценную информацию (или несколько ошибок, если в одном TrendResult
). Даже для непредвиденных ошибок, вы можете хранить детали вместо того, чтобы иметь неизвестную ошибку, которую трудно отследить.
если TrendResult
не имеет никаких элементов в перечислении, нет никаких проблем с ним. В противном случае, вы можете поместить информацию в журнал.
реализация следует за открытый/закрытый принцип, поэтому вам не нужно изменять реализацию, которая обрабатывает TrendResults
если возникают новые условия, которые приводят к ошибке.
для ваших бизнес-исключений, например при анализе ошибок необходимо создать определенные типы исключений, чтобы впоследствии анализировать эти ошибки на основе их типа.
поскольку IServerTrendProvider будет получать TrendResults с других компьютеров, вы не сможете использовать