Dilemma
Ho letto molti libri di best practice sulle pratiche orientate agli oggetti, e quasi tutti i libri che ho letto avevano una parte in cui dicono che le enumerazioni sono un odore di codice. Penso che abbiano perso la parte in cui spiegano quando le enumerazioni sono valide.
Pertanto, sto cercando le linee guida e / o casi d'uso in cui le enumerazioni sono NON un odore di codice e in effetti un costrutto valido.
Fonti:
"AVVERTENZA Come regola generale, le enumerazioni sono odori di codice e dovrebbero essere sottoposte a refactoring alle classi polimorfiche. [8]" Seemann, Mark, Dependency Injection in .Net, 2011, p. 342
[8] Martin Fowler et al., Refactoring: migliorare il design del codice esistente (New York: Addison-Wesley, 1999), 82.
Contesto
La causa del mio dilemma è un'API di trading. Mi danno un flusso di dati di tick inviando questo metodo:
void TickPrice(TickType tickType, double value)
dove enum TickType { BuyPrice, BuyQuantity, LastPrice, LastQuantity, ... }
Ho provato a creare un wrapper attorno a questa API perché la modifica delle interruzioni è il modo di vita di questa API. Volevo tenere traccia del valore di ogni ultimo tipo di tick ricevuto sul mio wrapper e l'ho fatto usando un dizionario di ticktypes:
Dictionary<TickType,double> LastValues
Per me, questo mi è sembrato un uso appropriato di enum se sono stati usati come chiavi. Ma ho dei ripensamenti perché ho un posto in cui prendo una decisione basata su questa collezione e non riesco a pensare a un modo in cui avrei potuto eliminare la dichiarazione dell'intervento, potrei usare una fabbrica ma quella fabbrica avrà ancora un passare la dichiarazione da qualche parte. Mi è sembrato che stavo solo spostando le cose ma ancora odora.
È facile trovare i NON FATTI delle enumerazioni, ma i DO, non così facile, e sarei grato se le persone possano condividere la loro esperienza, i pro e i contro.
Secondi pensieri
Alcune decisioni e azioni si basano su questi TickType
e non riesco a pensare a un modo per eliminare le dichiarazioni enum / switch. La soluzione più pulita che riesco a pensare è usare una factory e restituire un'implementazione basata su TickType
. Anche in questo caso avrò ancora una dichiarazione switch che restituisce un'implementazione di un'interfaccia.
Di seguito è elencata una delle classi di esempio in cui ho dei dubbi sul fatto che potrei utilizzare un enum errato:
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;
}
}
}