困境
我已经阅读了很多有关面向对象实践的最佳实践书籍,几乎我读过的每一本书都有一部分内容,他们说枚举是一种代码味道。我认为他们已经错过了解释枚举何时有效的部分。
因此,我正在寻找准则和/或用例,其中枚举不是代码的味道,而实际上是有效的构造。
资料来源:
“根据经验,枚举是代码的味道,应将其重构为多态类。[8]” Seemann,Mark,依赖注入,.Net,2011年,第2页。342
[8] Martin Fowler等人,《重构:改进现有代码的设计》(纽约:Addison-Wesley,1999年),第82页。
语境
我陷入困境的原因是交易API。通过以下方法,他们给了我Tick数据流:
void TickPrice(TickType tickType, double value)
哪里 enum TickType { BuyPrice, BuyQuantity, LastPrice, LastQuantity, ... }
我尝试过围绕该API进行包装,因为打破更改是该API的生活方式。我想跟踪包装器上最后收到的刻度线类型的值,并且通过使用ticktypes字典来做到这一点:
Dictionary<TickType,double> LastValues
在我看来,如果将它们用作键,这似乎是对枚举的正确使用。但是我有第二个想法,因为我确实有一个地方可以根据这个集合做出决定,而且我想不出一种消除消除switch语句的方法,我可以使用一个工厂,但是那个工厂仍然会有一个在某处切换语句。在我看来,我只是在移动东西,但仍然闻起来。
找到枚举的不容易,但是要做到的却不那么容易,如果人们可以分享他们的专业知识,利弊,我将不胜感激。
第二个想法
有些决定和行动是基于这些决定和行动的TickType
,我似乎想不出消除枚举/切换语句的方法。我能想到的最干净的解决方案是使用工厂并返回基于的实现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 ...