Dilemme
J'ai lu beaucoup de livres de bonnes pratiques sur les pratiques orientées objet, et presque tous les livres que j'ai lus avaient une partie où ils disent que les énumérations sont une odeur de code. Je pense qu'ils ont raté la partie où ils expliquent quand les énumérations sont valides.
En tant que tel, je recherche des directives et / ou des cas d'utilisation où les énumérations ne sont PAS une odeur de code et en fait une construction valide.
Sources:
"AVERTISSEMENT En règle générale, les énumérations sont des odeurs de code et doivent être refactorisées en classes polymorphes. [8]" Seemann, Mark, Dependency Injection in .Net, 2011, p. 342
[8] Martin Fowler et al., Refactoring: Improving the Design of Existing Code (New York: Addison-Wesley, 1999), 82.
Le contexte
La cause de mon dilemme est une API de trading. Ils me donnent un flux de données Tick en envoyant via cette méthode:
void TickPrice(TickType tickType, double value)
où enum TickType { BuyPrice, BuyQuantity, LastPrice, LastQuantity, ... }
J'ai essayé de créer un wrapper autour de cette API, car la rupture des changements est le mode de vie de cette API. Je voulais garder une trace de la valeur de chaque dernier type de tick reçu sur mon wrapper et je l'ai fait en utilisant un Dictionary of ticktypes:
Dictionary<TickType,double> LastValues
Pour moi, cela semblait être une bonne utilisation d'une énumération si elles étaient utilisées comme clés. Mais j'ai des doutes parce que j'ai un endroit où je prends une décision basée sur cette collection et je ne peux pas penser à un moyen d'éliminer la déclaration de changement, je pourrais utiliser une usine mais cette usine aura toujours un basculer la déclaration quelque part. Il me semblait que je ne fais que bouger mais ça sent encore.
Il est facile de trouver les NE PAS des énumérations, mais les DO, pas si faciles, et j'apprécierais que les gens puissent partager leur expertise, les avantages et les inconvénients.
Doutes
Certaines décisions et actions sont basées sur celles TickType
- ci et je n'arrive pas à penser à un moyen d'éliminer les instructions enum / switch. La solution la plus propre à laquelle je peux penser est d'utiliser une usine et de renvoyer une implémentation basée sur TickType
. Même alors, j'aurai toujours une instruction switch qui renvoie une implémentation d'une interface.
La liste ci-dessous est l'un des exemples de classes où j'ai des doutes quant à l'utilisation incorrecte d'une énumération:
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 ...