Hallo,
entschuldigt den etwas unpräzisen Betreff des Threads, aber mir ist keine treffende Beschreibung eingefallen.
Ich versuche kurz meine Gedankengänge für den folgende Problem darzulegen und erhoffe mir ein paar Anregungen eurerseits, da ich schon des Öfteren auf ähnliche Themen gestoßen bin.
Im aktuellen Fall gilt es Links zu unterschiedliche Finanzwebseiten bereitzustellen. Dabei ist der Eingabeparameter in den meisten Fällen ein Aktiensymbol, dass zu einem Link gewandelt werden soll. So wird aus MSFT (Aktiensymbol für die Microsoft Aktie) bei der Webseite Marketwatch zu
https://www.marketwatch.com/investing/stock/msft.
Im einfachsten Fall würde man eine statische Methode anbieten, die die Erstellung macht:
C#-Code: |
public static class MarketWatchLinkCreator
{
public static Uri CreateLink(string symbol)
{
return new Uri("https:
}
}
|
Nun ist das zwar ganz nett, weil man keine Instanzen erzeugen muss für die Linkgenerierung, aber es wäre ja auch schön, wenn man weitere Finanzwebseiten unter einer einheitlichen Schnittstelle generieren könnte. So könnte man SeekingAlpha in dem Gerüst unterbringen:
C#-Code: |
public interface ISymbolLinkCreator
{
Uri CreateLink(string symbol);
}
public class SeekingAlphaLinkCreator : ISymbolLinkCreator
{
public Uri CreateLink(string symbol)
{
return new Uri("https:
}
}
|
Jetzt gibt es aber Webseiten, wo das Aktiensymbol alleine nicht ausreicht. Man braucht dort bspw. noch die Heimatbörse um einen Link generieren zu können. Jetzt könnte man weitere Parameter entweder über den Konstruktor der Implementierung reinreichen (finde ich unsauber), oder man erweitert ISymbolLinkCreator um einen generischen Parameter.
C#-Code: |
public interface ISymbolLinkCreator<TInput>
{
Uri CreateLink(TInput input);
}
|
sodass TInput in diesem speziellen Fall eine Klasse aus Symbol und Heimatbörse wird.
Hat meiner Meinung nach einige Nachteile, ich habe irgendwie eine zu generische Benamung des Parameters und darf den auch laut einigen Code-Analyzern nicht in der Implementierung umbenennen. Ein "input" bleibt ein Input und wird besonders dann kritisch, wenn man z.B. zu Comdirect kommt. Dort kann man auch so einen Link generieren und man kann das gleiche Interface
C#-Code: |
ISymbolLinkCreator<string>
|
implementieren, jedoch ist dort "input" nicht das Aktiensymbol wie in 95% der anderen Fälle, sondern die ISIN. Das scheint für mich als Aufrufer verwirrend. Weiterhin bleibt die Instanzierung, die ich zum Schluss ansprechen möchte.
Angenommen, ich möchte alle Linkgeneratoren instanzieren und habe alle Daten da, wie würdet ihr eine Implementierung vornehmen um sowas zu vermeiden:
C#-Code: |
public class LinkCreator
{
private readonly IDataService _dataService;
public LinkCreator(IDataService dataService)
{
_dataService = dataService;
}
public IReadOnlyCollection<Uri> GetLinks(string symbol)
{
var links = new List<Uri>();
var seekingAlphaLink = new SeekingAlphaLinkCreator().CreateLink(symbol);
var marketWatchLink = new MarketWatchLinkCreator().CreateLink(symbol);
var isin = await _dataService.GetIsinAsync(symbol);
var comdirectLink = new ComDirectLinkCreator().CreateLink(isin);
var homeExchange = await _dataService.GetHomeExchangeAsync(symbol);
var furtherLink = new FurtherLinkCreator().CreateLink(new ComplexInput
{
HomeExchange = homeExchange,
Symbol = symbol
});
links.Add(seekingAlphaLink);
links.Add(marketWatchLink);
links.Add(comdirectLink);
links.Add(furtherLink);
return links;
}
}
|
Gerade was die Instanziierung angeht, habe ich mir überlegt, ob man das evtl. über eine Factory-Methode mit generischen Parametern anbietet und dann Activor.CreateInstance verwendet, aber man hätte 2 Typparameter verwenden müssen, was mir weniger intutiv vorkommt.
Vielleicht habt ihr ja eine Meinung. Ich wäre sehr dankbar :)