Dilemma
I've been reading a lot of best practice books about object oriented practices, and almost every book I've read had a part where they say that enums are a code smell. I think they've missed the part where they explain when enums are valid.
As such, I am looking for guidelines and/or use-cases where enums are NOT a code smell and in fact a valid construct.
Sources:
"WARNING As a rule of thumb, enums are code smells and should be refactored to polymorphic classes. [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.
Context
The cause of my dilemma is a trading API. They give me a stream of Tick data by sending thru this method:
void TickPrice(TickType tickType, double value)
where enum TickType { BuyPrice, BuyQuantity, LastPrice, LastQuantity, ... }
I've tried making a wrapper around this API because breaking changes is the way of life for this API. I wanted to keep track of the value of each last received tick type on my wrapper and I've done that by using a Dictionary of ticktypes:
Dictionary<TickType,double> LastValues
To me, this seemed like a proper use of an enum if they are used as keys. But I am having second thoughts because I do have a place where I make a decision based on this collection and I can't think of a way how I could eliminate the switch statement, I could use a factory but that factory will still have a switch statement somewhere. It seemed to me that I'm just moving things around but it still smells.
It's easy to find the DON'Ts of enums, but the DOs, not that easy, and I'd appreciate it if people can share their expertise, the pros and cons.
Second thoughts
Some decisions and actions are based on these TickType
and I can't seem to think of a way to eliminate enum/switch statements. The cleanest solution I can think of is using a factory and return an implementation based on TickType
. Even then I will still have a switch statement that returns an implementation of an interface.
Listed below is one of the sample classes where I'm having doubts that I might be using an enum wrong:
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 ...