дилемма
Я читал много лучших практических книг по объектно-ориентированным практикам, и почти в каждой прочитанной мной книге была часть, в которой говорится, что перечисления - это запах кода. Я думаю, что они пропустили ту часть, где они объясняют, когда перечисления действительны.
Поэтому я ищу руководящие принципы и / или варианты использования, в которых перечисления НЕ являются запахом кода и фактически являются допустимой конструкцией.
Источники:
«ПРЕДУПРЕЖДЕНИЕ. Как правило, перечисления являются запахами кода и должны быть преобразованы в полиморфные классы. [8]» Seemann, Mark, Dependency Injection, .Net, 2011, p. 342
[8] Мартин Фаулер и др., Рефакторинг: Улучшение дизайна существующего кода (Нью-Йорк: Аддисон-Уэсли, 1999), 82.
контекст
Причиной моей дилеммы является торговый API. Они дают мне поток данных о тиках, отправляя этот метод:
void TickPrice(TickType tickType, double value)
где enum TickType { BuyPrice, BuyQuantity, LastPrice, LastQuantity, ... }
Я попытался обернуть вокруг этого API, потому что ломать изменения - образ жизни для этого API. Я хотел отслеживать значение каждого последнего полученного типа тика в моей оболочке, и я сделал это с помощью словаря тиктипов:
Dictionary<TickType,double> LastValues
Мне это показалось правильным использованием перечисления, если они используются в качестве ключей. Но у меня возникают другие мысли, потому что у меня есть место, где я принимаю решение на основе этой коллекции, и я не могу придумать, как бы я мог исключить оператор switch, я мог бы использовать фабрику, но эта фабрика все еще будет иметь переключить заявление где-нибудь. Мне казалось, что я просто перемещаю вещи, но все еще пахнет.
Легко найти DON'Ts перечислений, но не так просто, и я был бы признателен, если бы люди могли поделиться своим опытом, плюсами и минусами.
Второстепенные мысли
Некоторые решения и действия основаны на них, TickType
и я не могу придумать способ устранить операторы enum / switch. Самым чистым решением, которое я могу придумать, является использование фабрики и возвращение реализации на основе TickType
. Даже тогда у меня все еще будет оператор switch, который возвращает реализацию интерфейса.
Ниже приведен один из примеров классов, где у меня есть сомнения, что я могу использовать неправильное перечисление:
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 ...