Interface declaration – latest vs historical

Imagine there is an interface IPriceProvider which supposed to serve 2 needs: historical and latest. So I think we have 2 options here.

First:

PriceInfo GetLatestPrice(string symbol);
PriceInfo GetHistoricalPrice(string symbol, DateTime pointInTime);

Second:

PriceInfo GetPrice(string symbol, DateTime pointInTime);

In my opinion the second one is better, cause it’s more flexible. Imagine, you have a Report which is as of now – so it calls this price provider like this:

GetPrice("EURUSD", _dateTime.Now);

So if there is a task to show what this exact report was showing yesterday at 17:35, I will just set _dateTime.Now to that point and my report will just work. But in case of the first approach, where I call it this way:

GetLatestPrice("EURUSD");

I will need to have a second implementation of IPriceProvider, then I will have wiring issue, I will need to configure my DI container in a special way and so on…

Am I missing something?
What are the Pros and Cons in these 2 approaches?

Update:

The Report class might look like this:

public class Report
{
    private readonly IDateTime _dateTime;

    private readonly IPriceProvider _priceProvider;

    public Report(IDateTime dateTime, IPriceProvider priceProvider)
    {
       _dateTime = dateTime;
       _priceProvider = priceProvider;
    }

    public void Run()
    {
        var latestPrice = _priceProvider.GetPrice("EURUSD", _dateTime.Now);
        // do the report calc here
    }
}

4

Judging from the conventions you’re using, you come from the C# world. Here’s how to solve this with an optional argument in C#:

public PriceInfo GetPrice(string symbol, DateTime pointInTime = null)

The idea is if you call this with only the string:

GetPrice("EURUSD");

then pointInTime will be it’s default value _dateTime.Now. If you have to, use some flag value like null to signal that a method needs to be called to get the value now. This way the above will be the same as:

GetPrice("EURUSD", _dateTime.Now);

5

I think you are actually mixing two different things here. One being the definition of an interface, the other an implementation detail of your report.

Regarding the design of the interface I would go for your first approach even though I would avoid the word Historical. Requirements can change and you might want to query a price which is not yet valid. Therefore I would define the interface like so:

PriceInfo GetCurrentPrice(string symbol);
PriceInfo GetPriceAt(string symbol, DateTime pointInTime);

In the report I would then use only GetPriceAt and pass DateTime.Today when no other date is specified. But as mentioned above this is an implementation detail.

Trả lời

Email của bạn sẽ không được hiển thị công khai. Các trường bắt buộc được đánh dấu *