I have a hierarchy of TrendProviders
which are used to provide a series of datapoints (trends) from different sources.
I have started with the generic interface:
public interface ITrendProvider<T> where T: TrendResult
{
IEnumerable<T> GetTrends();
}
TrendResult
is a result class with the obtained trend data and operation status code:
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
is as follows:
public enum TrendResultCode
{
OK,
DataParseError,
NoData,
UnknownError
}
There are also two types (so far) of more detailed interfaces:
IFileTrendProvider
- used to obtain trends from any files.
IServerTrendProvider
- used to obtain trends from remote servers, using FTP for example.
IFileTrendProvider
goes like this:
public interface IFileTrendProvider : ITrendProvider<TrendResult>
{
IFileReader FileReader {get; set}
FileTrendDiscoveryPattern Pattern {get; set;}
}
IServerTrendProvider
goes like this:
public interface IServerTrendProvider : ITrendProvider<TrendResult>
{
IClient Client { get; set; }
Dictionary<string, string[]> RequestedServerTrendIDs { get; set; }
}
The concrete classes that implements the interfaces are as follows:
One of FileTrend
type:
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
}
}
And one of the ServerTrend
type:
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
}
}
Now, what I want to achieve and where I need your help and advice:
The IFileReader
introduces its own error codes:
public enum FileReadResultCode
{
OK,
FileAlreadyOpen,
FileNotFound,
UnknownError
}
IClient
also introduces its specific operation error codes:
public enum ClientCode
{
OK,
InvalidCredentials,
ResourceNotFounds,
UnknownError
}
As both: IFileReader
and IClient
also returns its own error codes, how could I intruduce them in the TrendResult
object returned by GetTrends()
method, so that in the end there will be also some information about the "internal" error, not only TrendResult
specific error?
I would need some flexible solution - I was thinking about inheriting from TrendResult
and create a FileTrendResult
and ServerTrendResult
for each of concrete providers, and also define a specific error enumerations for both so that they return its own result type, but can it be done in some other way?
C programming language is a machine-independent programming language that is mainly used to create many types of applications and operating systems such as Windows, and other complicated programs such as the Oracle database, Git, Python interpreter, and games and is considered a programming foundation in the process of ...
In the real sense it has no meaning or full form. It was developed by Dennis Ritchie and Ken Thompson at AT&T bell Lab. First, they used to call it as B language then later they made some improvement into it and renamed it as C and its superscript as C++ which was invented by Dr. Stroustroupe.
C is a general-purpose language that most programmers learn before moving on to more complex languages. From Unix and Windows to Tic Tac Toe and Photoshop, several of the most commonly used applications today have been built on C. It is easy to learn because: A simple syntax with only 32 keywords.
C is more difficult to learn than JavaScript, but it's a valuable skill to have because most programming languages are actually implemented in C. This is because C is a “machine-level” language. So learning it will teach you how a computer works and will actually make learning new languages in the future easier.
Instead of having a pre-defined list of possible errors in the enumerations (TrendResultCode
, FileReadResultCode
, ClientCode
, ...) you could change the TrendResult
class to store a list of exceptions and get rid of the enumerations:
public class TrendResult
{
// ...
// public TrendResultCode Code { get; set; }
public IEnumerable<Exception> Errors { get; set; }
// ...
}
This way, you can store the complete information of the error including stack trace and other valuable information (or of several errors if there is more than one problem in a single TrendResult
). Even for unexpected errors, you are able to store the details instead of having an unknown error that is hard to track down.
If a TrendResult
does not have any items in the enumeration, there are no problems with it. Otherwise, you can put the information to the log.
The implementation follows the Open/Closed principle, so you don't have to change the implementation that handles the TrendResults
if there are new conditions that lead to an error.
For your business exceptions, e.g. parsing errors, you should create specific exception types so that you are able to analyze these errors later on based on their type.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With