Dilema
Eu tenho lido muitos livros de práticas recomendadas sobre práticas orientadas a objetos, e quase todos os livros que li tiveram uma parte em que eles dizem que as enums são um cheiro de código. Eu acho que eles perderam a parte em que explicam quando as enums são válidas.
Como tal, estou procurando diretrizes e / ou casos de uso em que as enumerações NÃO são um cheiro de código e, de fato, são uma construção válida.
Fontes:
"AVISO Como regra geral, as enums são odores de código e devem ser refatoradas para classes polimórficas. [8]" Seemann, Mark, Injection Dependency in .Net, 2011, p. 342
[8] Martin Fowler et al., Refatoração: Melhorando o Design do Código Existente (Nova York: Addison-Wesley, 1999), 82.
Contexto
A causa do meu dilema é uma API de negociação. Eles me fornecem um fluxo de dados do Tick enviando este método:
void TickPrice(TickType tickType, double value)
Onde enum TickType { BuyPrice, BuyQuantity, LastPrice, LastQuantity, ... }
Eu tentei criar um invólucro em torno dessa API porque quebrar alterações é o modo de vida dessa API. Eu queria acompanhar o valor de cada último tipo de tick recebido no meu wrapper e fiz isso usando um Dictionary of ticktypes:
Dictionary<TickType,double> LastValues
Para mim, isso parecia um uso adequado de um enum se eles fossem usados como chaves. Mas estou pensando duas vezes porque tenho um lugar onde tomo uma decisão com base nesta coleção e não consigo pensar em como eliminar a declaração do interruptor, poderia usar uma fábrica, mas essa fábrica ainda terá um mude a declaração em algum lugar. Pareceu-me que estou apenas mudando as coisas, mas ainda cheira.
É fácil encontrar o NÃO das enumerações, mas as DOs, não tão fáceis, e eu apreciaria se as pessoas pudessem compartilhar seus conhecimentos, os prós e os contras.
Segundas intenções
Algumas decisões e ações são baseadas nelas TickType
e não consigo pensar em uma maneira de eliminar enumerações / alternar declarações. A solução mais limpa que consigo pensar é usar uma fábrica e retornar uma implementação com base TickType
. Mesmo assim, ainda terei uma instrução switch que retorna a implementação de uma interface.
Listada abaixo está uma das classes de exemplo em que estou com dúvidas de que possa estar usando uma enumeração errada:
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 ...