Dilemma
Ich habe viele Best-Practice-Bücher über objektorientierte Praktiken gelesen, und fast jedes Buch, das ich gelesen habe, enthielt einen Teil, in dem Enums als Codegeruch bezeichnet werden. Ich denke, sie haben den Teil verpasst, in dem sie erklären, wann Aufzählungen gültig sind.
Als solches suche ich nach Richtlinien und / oder Anwendungsfällen, bei denen Aufzählungen KEIN Codegeruch und tatsächlich ein gültiges Konstrukt sind.
Quellen:
"WARNUNG Als Faustregel gilt, dass Aufzählungen Code-Gerüche sind und in polymorphe Klassen umgewandelt werden sollten. [8]" Seemann, Mark, Dependency Injection in .Net, 2011, p. 342
[8] Martin Fowler et al., Refactoring: Verbesserung des Entwurfs bestehender Codes (New York: Addison-Wesley, 1999), 82.
Kontext
Die Ursache meines Dilemmas ist eine Handels-API. Sie geben mir einen Stream von Tick-Daten, indem sie diese Methode senden:
void TickPrice(TickType tickType, double value)
wo enum TickType { BuyPrice, BuyQuantity, LastPrice, LastQuantity, ... }
Ich habe versucht, einen Wrapper für diese API zu erstellen, da das Brechen von Änderungen die Lebensweise dieser API ist. Ich wollte den Wert jedes zuletzt empfangenen Tick-Typs auf meinem Wrapper verfolgen und habe dazu ein Wörterbuch mit Ticktypen verwendet:
Dictionary<TickType,double> LastValues
Für mich schien dies die richtige Verwendung einer Aufzählung zu sein, wenn sie als Schlüssel verwendet werden. Aber ich habe Bedenken, weil ich einen Ort habe, an dem ich basierend auf dieser Sammlung eine Entscheidung treffen kann, und ich kann mir keine Möglichkeit vorstellen, wie ich die switch-Anweisung beseitigen könnte. Ich könnte eine Factory verwenden, aber diese Factory wird immer noch eine haben switch-Anweisung irgendwo. Es schien mir, dass ich nur Dinge bewege, aber es riecht immer noch.
Es ist einfach, das NICHT von Aufzählungen zu finden, aber die DOs, nicht so einfach, und ich würde es begrüßen, wenn die Leute ihre Fachkenntnisse, die Vor- und Nachteile teilen können.
Bedenken
Einige Entscheidungen und Aktionen basieren auf diesen TickType
und ich kann mir keine Möglichkeit vorstellen, Enum- / Switch-Anweisungen zu eliminieren. Die sauberste Lösung, die ich mir vorstellen kann, ist die Verwendung einer Factory und die Rückgabe einer Implementierung auf der Basis TickType
. Selbst dann habe ich noch eine switch-Anweisung, die eine Implementierung einer Schnittstelle zurückgibt.
Im Folgenden ist eine der Beispielklassen aufgeführt, in denen ich Zweifel habe, dass ich möglicherweise eine falsche Aufzählung verwende:
public class ExecutionSimulator
{
Dictionary<TickType, double> LastReceived;
void ProcessTick(TickType tickType, double value)
{
//Store Last Received TickType value
LastReceived[tickType] = value;
//Perform Order matching only on specific TickTypes
switch(tickType)
{
case BidPrice:
case BidSize:
MatchSellOrders();
break;
case AskPrice:
case AskSize:
MatchBuyOrders();
break;
}
}
}
enums as switch statements might be a code smell ...