Dilemma
Ho letto molti libri di buone pratiche sulle pratiche orientate agli oggetti e quasi tutti i libri che ho letto hanno avuto una parte in cui affermano che gli enum sono un odore di codice. Penso che abbiano perso la parte in cui spiegano quando le enumerazioni sono valide.
Come tale, sto cercando linee guida e / o casi d'uso in cui gli enum NON sono un odore di codice e in realtà un costrutto valido.
fonti:
"AVVERTENZA Come regola generale, gli enum sono odori di codice e dovrebbero essere sottoposti a refactoring in classi polimorfiche. [8]" Seemann, Mark, Dependency Injection in .Net, 2011, p. 342
[8] Martin Fowler et al., Refactoring: migliorare la progettazione 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 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é interrompere le modifiche è il modo di vivere 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 sembrava un uso corretto di un enum se venivano usati come chiavi. Ma sto ripensandoci perché ho un posto in cui prendo una decisione basata su questa raccolta e non riesco a pensare a un modo in cui potrei eliminare l'istruzione switch, potrei usare una fabbrica ma quella fabbrica avrà ancora un istruzione switch da qualche parte. Mi è sembrato di spostare le cose, ma ha ancora un odore.
È facile trovare le cose da non fare degli enum, ma le DO, non così facili, e lo apprezzerei se le persone potessero condividere le loro competenze, i pro ei contro.
Ripensamenti
Alcune decisioni e azioni si basano su queste TickType
e non riesco a pensare a un modo per eliminare le dichiarazioni enum / switch. La soluzione più pulita a cui riesco a pensare è usare una fabbrica e restituire un'implementazione basata su TickType
. Anche allora avrò comunque un'istruzione switch che restituisce un'implementazione di un'interfaccia.
Di seguito è elencata una delle classi di esempio in cui ho dubbi sul fatto che potrei usare un enum sbagliato:
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 ...