我只是在查看我的一些旧代码(有一些空闲时间),我注意到了一个相当冗长的switch语句。由于获得了新的知识,我已经以下面的形式重构了它:
private Dictionary<string, Action> createView
{
get
{
return new Dictionary<string, Action>()
{
{"Standard", CreateStudySummaryView},
{"By Group", CreateStudySummaryByGroupView},
{"By Group/Time", CreateViewGroupByHour}
};
}
}
您是否会考虑这种良好做法,或者这仅仅是一个超级丰富且不必要的案例?我渴望确保我学到的新技术,仅仅为了它而不是聪明,并且它们实际上为代码增加了好处。
感谢。
答案 0 :(得分:18)
长切换语句是一种经典的难闻气味,并且始终是重构的目标。
此处执行的“标准”步骤是Replace Conditional with Polymorphism。这是Martin Fowler的书Refactoring(11年前出版于1999年)中列出的步骤之一。
现在处理像对象这样的函数非常容易(例如使用Action),这可能是一个很好的解决方案。
不,我不认为你为此而聪明。如果我想在将来添加其他选项,我可以很容易地看到需要做什么。
答案 1 :(得分:9)
根据您的应用程序,您可以避免始终构造新的字典对象,但将其声明为类成员,在首次访问时初始化并始终返回相同的实例。但很难说,它是否真的符合您的需求。 像这样我的意思是
public class MyClass
{
Dictionary<string, Action> dict = null;
private Dictionary<string, Action> createView
{
get
{
if(dict == null)
{
dict = new Dictionary<string, Action>()
{
{"Standard", CreateStudySummaryView},
{"By Group", CreateStudySummaryByGroupView},
{"By Group/Time", CreateViewGroupByHour}
};
}
return dict;
}
}
}
修改强>
从概念的角度来看,我用字典swicth/case
替换长TryGetValue
是一个非常好的解决方案。
希望这会有所帮助......
答案 2 :(得分:5)
这种方法很棒。
我使用的不只是Action
。它对滤波器和选择器也非常有效。类似的东西:
var filters = new Dictionary<string, Func<MyEntity, bool>>()
{
// ...
};
var query = entities.Where(filters["X"]);
答案 3 :(得分:2)
如果代码一经编写,在很大程度上是静态的,不会有太大的变化,那么我就会遇到switch
。至少在表面上,你的字典方法很适合于更具动态性 - 这是基于更多的要求。
至于使用这种方法用代码替换各地的交换机,我个人在大多数情况下都不这样做。我的诚实意见是,为了它而只是聪明,但它仍然很容易维护。正如我所见,个人对最佳实践的品味是最重要的因素。
另一方面,正如其他人所说,这可能是长切换语句的可行解决方案。然后,像Strategy Pattern这样的东西也是支持行为变化的好方法。