在调用其他函数时减少if语句
本文关键字:if 语句 调用 其他 函数 | 更新日期: 2023-09-27 18:21:57
我有一个函数,它从不同的对象调用许多其他函数。在调用下一个函数之前,每个函数都必须返回true。正如你所看到的,我使用了太多if语句。如何改进代码并使其更整洁?感谢
bool ISOKToDoSomthing()
{
boo retVal = false;
retVal = ObjA.CheckVersion(oldVersion);
if(retVal)
{
retVal = objB.CheckUserRight();
}
if(retVal)
{
retVal = ObjC.ISDBExist();
}
if(retVal)
{
retVal = OjbD.ISServerUp(ServerName);
}
//tons of similar code as above
.........
return retVal;
}
return
ObjA.CheckVersion(oldVersion) &&
objB.CheckUserRight() &&
ObjC.ISDBExist() &&
OjbD.ISServerUp(ServerName);
我的建议是:如果没有进行更改的明确业务案例,就不要对此代码执行任何操作。
您的代码清晰、明显、可能正确、易于维护和调试你到底为什么要以任何方式改变它?花时间通过修复bug和添加功能来增加价值,而不是不必要地更改工作代码。当你的老板问你"那么你今天做了什么?"答案不应该是"我对正确的、有效的、已经调试好的代码进行了不必要的修饰性更改,从而增加了我们的日程风险"。
现在,如果这里真的有问题,问题可能不是代码难以阅读,而是代码严格地编码了应该是用户可配置的业务流程。在这种情况下,创建一个名为"工作流"的对象,对业务流程进行编码,并创建一个评估任意工作流的引擎。然后根据用户的输入构建一个表示所需工作流的对象实例。
这实际上为用户增加了价值;用户一点也不在乎您是否使用嵌套的"if"语句。
if (!ObjA.CheckVersion(oldVersion)) return false;
if (!ObjB.CheckUserRight()) return false;
if (!ObjC.IsDBExist()) return false;
if (!ObjD.IsServerUp(serverName)) return false;
... your other checks ...
return true;
&&
的短路在一些情况下是有用的,但如果你有"大量"的短路,IMO就太多了,不能拘泥于一句话。
不过,两者的结合可能是有用的。更有用的是将这些检查中的一些压缩成更大的块(但比IsOKToDoSomething
小)。例如,检查您是否可以同时访问数据库(数据库是否存在,是否可以登录,等等)
说实话,你有这么多对象要检查,这一事实暗示了设计问题——也就是说,你试图一次做太多,或者你有一个"上帝对象",它的小触角遍布系统的各个方面。你可能需要考虑解决这个问题。
return ObjA.CheckVersion(oldVersion) && objB.CheckUserRight() && ObjC.ISDBExist() && OjbD.ISServerUp(ServerName)
&运营商会短路,所以你可以这样链他们:
bool ISOKToDoSomthing()
{
return
ObjA.CheckVersion(string oldVersion) &&
objB.CheckUserRight() &&
ObjC.ISDBExist() &&
OjbD.ISServerUp(ServerName) &&
//tons of similar code as above
.........
}
bool ISOKToDoSomthing()
{
return ObjA.CheckVersion(string oldVersion) &&
ObjB.CheckUserRight() &&
ObjC.ISDBExist() &&
OjbD.ISServerUp(ServerName);
}
也许?
retVal = objB.CheckUserRight() && ObjC.ISDBExist() && OjbD.ISServerUp(ServerName);
等等。
附带说明的是,例如,在一条语句中调用方法之前,您可以测试objB是否为null(一旦条件不满足,代码就会中断执行,即不会调用下一个条件),因此您不需要很多if(objB!=null)类型的语句。例如:
retVal = (objB != null && objB.CheckUserRight()) && (ObjC != null && ObjC.ISDBExist()) && (OjbD != null && OjbD.ISServerUp(ServerName));
您可以利用C#进行短路评估的事实:
return
ObjA.CheckVersion(oldVersion) &&
objB.CheckUserRight() &&
ObjC.ISDBExist() &&
OjbD.ISServerUp(ServerName);
编辑以修复CheckVersion参数的语法
如何使用and
:
retVal = ObjA.CheckVersion(oldVersion) &&
objB.CheckUserRight() &&
ObjC.ISDBExist() &&
OjbD.ISServerUp(ServerName);
return retval;
为了让代码不那么冗长,可以尝试while循环。假设您的方法是,如果它/ever/变为false,则永远不更改原始值的值,那么它将是while(retval){}并迭代一系列操作。就我个人而言,我认为这很丑陋。考虑使用一个开关,甚至(没错,但它会起作用)一个逐位枚举。
从我的角度来看,当我看到自己写这样的代码时,我在某个地方犯了一个严重的架构错误,我真的应该重新思考发出这个呼吁的原因。也许您应该重新审视一下您的逻辑,而不仅仅是您的代码。坐下来画一些方框,在设计阶段多做一些工作,你可能会发现自己的构建方式非常不同。
edit:或者,是的,像其他人一样,你可以让你的迭代成为一个if语句。同样,这是一个比一长串布尔值更大的问题。
这取决于您想要更改的内容。也许您可以抛出一个异常,而不是从子方法返回bool
。
bool retVal = true;
try
{
ObjA.CheckVersion(oldVersion);
objB.CheckUserRight();
ObjC.ISDBExist();
OjbD.ISServerUp(ServerName);
}
catch (SomeException ex)
{
// Log ex here.
retVal = false;
}
return retVal;
如果你这样做,IsDBExist
可能不是最好的名字(因为在我看来,Is通常翻译为"返回bool"),但你会明白的。