代码重构c#围绕几个执行相同检查的if语句提问
我有一个方法,其中包含大量的if语句,这似乎有点愚蠢,尽管我不确定如何改进代码 这里有一个例子。这个逻辑在控制器中的视图中,现在更好了,但是是否有我遗漏的东西,可能是一个设计模式,阻止我检查panelCount代码重构c#围绕几个执行相同检查的if语句提问,c#,.net,asp.net-mvc,refactoring,C#,.net,Asp.net Mvc,Refactoring,我有一个方法,其中包含大量的if语句,这似乎有点愚蠢,尽管我不确定如何改进代码 这里有一个例子。这个逻辑在控制器中的视图中,现在更好了,但是是否有我遗漏的东西,可能是一个设计模式,阻止我检查panelCount
if (model.Train && panelCount < NumberOfPanelsToShow)
{
panelTypeList.Add(TheType.Train);
panelCount++;
}
if (model.Car && panelCount < NumberOfPanelsToShow)
{
panelTypeList.Add(TheType.Car);
panelCount++;
}
if (model.Hotel && panelCount < NumberOfPanelsToShow)
{
panelTypeList.Add(TheType.Hotel);
panelCount++;
}
...
if(model.Train&&panelCount
不确定您将此设计模式称为什么。但我曾经读到,每当你发现自己在为不同类型重复代码块时(就像你正在做的那样),你最好把这个功能放到对象本身中去
你可以这样把它打破:
private const NumberOfPanelsToShow = 4;
private int panelCount = 0;
private void addToPanel(IPanelAddable element, PanelList panelTypeList) {
if(panelCount < NumberofPanelsToShow) {
element.addToPanelTypeList(panelTypeList);
panelCount++;
}
}
实际上,您希望避免上述情况,简化上述/w基类,等等。。。。然后,您的TheType.*对象显然需要实现“addToPanelTypeList”方法:
您可以使用接口或继承来实现相同的目标…我可能要做的是在模型上设置一个要切换的枚举类型
if(panelCount < NumberOfPanelsToShow)
{
switch(model.modelType)
{
case Model.Car:
// do stuff
break;
}
panelCount++;
}
if(panelCount
不过,我们需要更多的信息来确定如何处理这些案例,以及在任何给定时间可以应用多少条件
更新
考虑到您提供的其他信息,这里的一些其他答案似乎更合适。考虑到您当前的情况,这个答案是不够的。通常重构的方法是多态性地进行重构,并负责决定如何处理对象,但由于您的决定基于同一对象的不同方面,我不确定您是否可以在这里这样做 我很想重构成一个方法:
public AddIfSpace(bool thingToTest, TheType typeToAdd, ref currentCount)
{
if (currentCount<NumberOfPanelsToShow && thingToTest)
{
panelTypeList.Add(typeToAdd);
currentCount++;
}
}
根据变量的作用域,您可能需要更少或更多的参数,如果panelTypeList类型的作用域受到限制,您可以将其作为panelTypeList类型的扩展方法,这样您就可以得到如下结果:
panelTypeList.AddIfSpace(model.Car,TheType.Car,ref panelCount);
panelTypeList.AddIfSpace(model.Train,TheType.Train,ref panelCount);
panelTypeList.AddIfSpace(model.Hotel,TheType.Hotel,ref panelCount);
这至少避免了代码中重复的逻辑,意味着如果您想更改检查的工作方式,并且如果您很好地命名了方法,您可以在一个地方进行修改,这应该传达意图并使代码更具可读性。现在没有VS来测试编译代码,但这应该传达逻辑。 您可以使用尽可能多的类型构建数组列表,而不必使用大的if-else或switch语句重复测试逻辑
TheType[] typesWithPanel = new TheType[] { TheType.Train, TheType.Car, TheType.Hotel};
if (typesWithPanel.Contains(model.ModelType) && panelCount < NumberOfPanelsToShow)
{
panelTypeList.Add(model.ModelType);
panelCount++;
}
type[]typesWithPanel=new TheType[]{type.Train,type.Car,type.Hotel};
if(typesWithPanel.Contains(model.ModelType)&&panelCount
假设Model.Train、Model.Car、Model.Plane只是“Model”类型的布尔指示器(而不是创建Train:Model、Plane:Model等)
在你的测试中:
if(panelCount < NumberOfPanelsToShow)
switch (Model.ModelType)
{
case ModelType.Train :
...
break;
case ModelType.Plane :
...
}
if(panelCount
然而,由于Car、PLane和Train是不同的,所以您确实应该有一个基本类型模型,从模型中派生Car、PLane和Train,然后您可以重载方法来处理每种类型
if (panelCount < NumberOfPanelsToShow)
{
panelCount += AddModel(model);
}
private int AddModel(Plane model)
{ // do plane stuff here and on success return 1 else 0; }
private int AddModel(Train model)
{ // do train stuff here and on success return 1 else 0; }
private int AddModel(Car model)
{ // do car stuff here and on success return 1 else 0; }
if(panelCount
我想尝试一下,做一些假设
看起来您有某种“Panel”类,试图用数据模型对象(汽车、酒店、火车等)的信息填充该类。取而代之的是,为什么不使用带有多态面板类(或IPanel接口)和CarPanel、HotelPanel、TrainPanel等子类的类型模式呢。。。使用ViewModel对象,视图代码变得更加简单:
var newPanel = PanelFactory.GetPanel(data); //Returns a CarPanel, HotelPanel, TrainPanel...
panelTypeList.Add(newPanel);
panelCount++;
您可以随时查看规范模式。对于布尔逻辑非常方便:
public interface ISpecification<T>
{
public bool IsSatisfiedBy(T candidate);
}
公共接口规范
{
公共学校(T候选人)满意;
}
如果不知道所涉及的类型,例如酒店/汽车/火车属性的类型,以及类型类型,则很难对其进行重构。这有帮助吗?公共枚举类型{Hotel=0,Car=1,Train=2}@James:有一点,但是我们可以了解更多关于模型表示的内容。例如,model.Car和model.Hotel都是真的吗?类型基本上控制要渲染的视图。。因此,它们可能都是真实的,并同时显示,因为它们是局部视图,或者只是部分视图,或者根本没有视图。希望这能有所帮助,谢谢大家的贡献。@James:在这种情况下,检查的顺序非常重要,panelCount
检查可能是真的,然后是假的……如果成功,你不应该返回1吗?
if(panelCount < NumberOfPanelsToShow)
switch (Model.ModelType)
{
case ModelType.Train :
...
break;
case ModelType.Plane :
...
}
if (panelCount < NumberOfPanelsToShow)
{
panelCount += AddModel(model);
}
private int AddModel(Plane model)
{ // do plane stuff here and on success return 1 else 0; }
private int AddModel(Train model)
{ // do train stuff here and on success return 1 else 0; }
private int AddModel(Car model)
{ // do car stuff here and on success return 1 else 0; }
var newPanel = PanelFactory.GetPanel(data); //Returns a CarPanel, HotelPanel, TrainPanel...
panelTypeList.Add(newPanel);
panelCount++;
public interface ISpecification<T>
{
public bool IsSatisfiedBy(T candidate);
}