帮助重构这个混乱的嵌套 if 方法
好吧,我想要一些意见,如何解决这个混乱的方法!
它有很多嵌套的“if”语句。
但意识到我必须确切地知道该方法在哪里失败,目前在每个相应的“else”子句中我正在记录错误(失败的“if”条件”)。
注意:忽略事物背后的任何逻辑,请关注样式和结构,因为我已经编写了所有函数名称等。
这是骨架结构:
public void MyMethod()
{
try
{
bool tryAgain = false;
string filename = DownloadFile();
if( IsFileFormatOk(filename) )
{
blah = GetBlah(filename);
if(blah.ID > 0)
{
if(ImportFile(filename)
{
string username = GetUserFromFile(filename);
if(isValidUser(username))
{
// few more levels to go
//
//
//
}
else
{
LogError(filename, ...); // specific to this if statement
tryAgain = true;
}
}
else
{
LogError(filename, ...); // specific to this if statement
tryAgain = true;
}
}
else
{
LogError(filename, ...); // specific to this if statement
tryAgain = true;
}
}
else
{
LogError(filename, ...); // specific to this if statement
tryAgain = true;
}
}
catch
{
}
finally
{
if(tryAgain)
{
// blah
}
}
}
Ok I want some opinions how I can fix this mess of a method!
It has WAY to many nested 'if' statements.
But realize I have to know exactly where the method fails, currently in each of the respective 'else' clause I am logging the error (the failed 'if' condition').
Note: ignore any logic behind the things, please focus on the style and structure as I have made all the function names up etc.
Here is the skeleton structure:
public void MyMethod()
{
try
{
bool tryAgain = false;
string filename = DownloadFile();
if( IsFileFormatOk(filename) )
{
blah = GetBlah(filename);
if(blah.ID > 0)
{
if(ImportFile(filename)
{
string username = GetUserFromFile(filename);
if(isValidUser(username))
{
// few more levels to go
//
//
//
}
else
{
LogError(filename, ...); // specific to this if statement
tryAgain = true;
}
}
else
{
LogError(filename, ...); // specific to this if statement
tryAgain = true;
}
}
else
{
LogError(filename, ...); // specific to this if statement
tryAgain = true;
}
}
else
{
LogError(filename, ...); // specific to this if statement
tryAgain = true;
}
}
catch
{
}
finally
{
if(tryAgain)
{
// blah
}
}
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(7)
我将努力更改您的逻辑,以便您可以尽快从该方法返回,而不是嵌套更多逻辑。 例如:
这可能有助于删除一些嵌套并使事情变得不那么复杂。
I would work on changing your logic so you can return from the method as soon as possible instead of nesting more logic. Fore example:
This may help remove some nesting and make things less complicated.
我猜想有相当多的逻辑等待在其他地方提取,但无论如何,这里有另一种扁平化嵌套的方法:
I would guess there's quite a bit of logic that's waiting to be extracted elsewhere, but in any case here's another way to flatten the nesting:
您可以首先将顶级 if (true 分支) 放入单独的方法中。 并继续直到满意为止。
因此,通常您将: 更改
为
请注意需要传递给新方法的局部变量。
You can start by putting the toplevel if (true branch) in a separate method. And continue until satisfied.
So generally you change:
Into
Please beware of the local variables that need to be passed tot the new method.
您应该尝试让您调用的所有方法在发生错误时抛出异常。 抛出的异常应该包含您希望记录的任何错误消息。 创建一个 LogError() 方法,该方法接受任何异常并记录嵌入的消息。 像这样(伪代码):
当然,您必须创建所有这些异常,但这非常简单。 在大多数语言中,您只需对顶级 Exception 对象进行子类化即可。
You should try having all of the methods that you are calling throw an exception in case of an error. The exceptions thrown should contain whatever error message you wish to log. Create a LogError() method which takes any exception and logs the embedded message. Like this (pseudo-code):
Of course, you will have to create all of those Exceptions, but that is pretty trivial. In most languages you just subclass whatever the top level Exception object is.
编辑:既然我知道有这么多级别,我们需要采取另一种方法。 我不知道“重试”位中有什么,但您需要更改逻辑,以便它测试失败案例,而不是成功案例。 如果失败,记录并返回(或以某种方式执行重试所需的任何操作)。 否则,你可以继续跳出“如果”。
在我知道嵌套 if 的级别之前,我提出了以下建议。
我确信您可以对此进行更多重构,并将
// 等
拉入新方法中。 这取决于您需要来回传递多少东西。 如果您传递的参数太多,请考虑作为参数或类字段是否更有意义。Edit: Now that I know there are so many levels, we need to take another approach. I don't know what's in the "try again" bit, but you need to change around the logic so it tests for a failure case, not a success case. If it fails, log and return (or somehow do whatever try again entails). Otherwise, you can keep going outside the if.
Before I knew there were many more levels of nested if, I suggested the following.
I'm sure you could refactor this a bit more and pull the
// and so forth
into a new method as well. It depends on how much stuff you're going to have to pass back and forth. And if you're passing too much, consider if it makes more sense to be a parameter or a class field.这是 jjnguy 的建议,已实施:
Here's jjnguy's suggestion, implemented:
对于这类问题,http://refactormycode.com/ 非常有用。
尽管 SO 人员也确实致力于重构一些代码。 ;)
For these kind of questions, http://refactormycode.com/ is very useful.
Although the SO people are really committed to refactoring some code, too. ;)