If语句:处理具有相同条件的分层的最佳方法

时间:2016-01-06 16:04:16

标签: c# if-statement

我对编程很陌生,但我一直在努力确保学习良好的设计实践。我的问题与如何处理这种if-statement情况有关,因为它似乎违反了Don't Repeat Yourself

我有一个带有构造函数的类,其中包含一个连接数据库的方法。如果连接代码块中存在错误,则该方法将写入string。然后,我有一个分析数据库元数据的进程方法,如果找到任何数据库,也会写入错误。如果连接方法中已经存在错误,我不希望运行元数据分析,但这是最好的方法吗?:

public bool Process()
{
    if (ErrorLog == null)
    {
        //Metadata analysis code that may write errors

        if (ErrorLog == null)
            return true;
        else
            PublishErrorLog();
        return false;
    } 
    else
        PublishErrorLog();
    return false;
}

3 个答案:

答案 0 :(得分:3)

你的最终功能看起来很简单:

[alexus@j ~]$ git clone https://github.com/a1exus/jt4cb.git
Cloning into 'jt4cb'...
remote: Counting objects: 32, done.
remote: Total 32 (delta 5), reused 5 (delta 5), pack-reused 26
Unpacking objects: 100% (32/32), done.
Checking connectivity... done.
[alexus@j ~]$ cd jt4cb/
[alexus@j ~/jt4cb]$ git branch --all
* master
  remotes/origin/HEAD -> origin/master
  remotes/origin/master
[alexus@j ~/jt4cb]$ ls
README.md
[alexus@j ~/jt4cb]$ 

<强>解释

如果带有public bool Process() { if (hasError()) return false; //Metadata analysis code that may write errors //Note that error log may change here return !hasError(); //updated by juharr } 的行实际上可以更改//metadata analysis的状态,则您提供的代码可能不完全相同。

简化步骤1:单个If-Else循环

然而,看到你的嵌套循环,我宁愿让代码变得更容易处理和通过做这样的事情来阅读

ErrorLog

基本上,您可以创建可以先返回的简单语句,而不是使用嵌套的if-else。如果满意则返回,否则继续。

这样,你的代码就变成了单个条件循环 - 没有嵌套循环。

简化步骤2:错误日志+具有错误组合功能

您可以进一步改进上面的代码,假设您的错误记录模式相同,您可以创建这样的函数

public bool Process()
{
    if (ErrorLog != null){
        PublishErrorLog();
        return false;
    }
        //Metadata analysis code that may write errors
       //Note that error log may change here

    if (ErrorLog != null){
        PublishErrorLog();
        return false;
    }

    return true;
}

最终代码

然后bool hasError(){ if (ErrorLog != null){ PublishErrorLog(); return true; } return false; //no error, can continue } 函数看起来像

Process

非常简洁。你也可以在其他地方重复这种模式。

答案 1 :(得分:2)

其他答案有效。但对我来说,这似乎是使用Exceptions的完美案例。你随时写信ErrorLog也会抛出异常。然后,您可以在顶部只有一个块来处理错误。

public bool Process()
{
    if (ErrorLog != null)
        //At this point, the PublishErrorLog should have already been called.
        return false;

    try
    {
        // Do Metadata analysis that may throw errors
    }
    catch (ErrorLogException e)
    {
        PublishErrorLog()
        return false;
    }
    return true;
}

这样做的好处是,元数据分析可以根据需要进行复杂和嵌套。它只需要抛出异常。

编辑:

正如Aron所指出的,这可以在没有ErrorLog作为类成员的情况下完成。日志信息可以存储在异常本身中。 catch块看起来像:

catch (ErrorLogException e)
{
    var logMessage = e.logMessage;
    PublishErrorLog(logMessage);
    return false;
}

答案 2 :(得分:1)

您似乎正在使用ErrorLog属性来表示您的连接的有效性。如果ErrorLog是一个字符串,正如我从您的问题中所理解的那样,我将有一种特定的方式来判断连接是否有效,并且不依赖于日志的无效。

e.g。

public bool Process()
{
    if (HasValidConnection)
    {
        //Metadata analysis code that may write errors
    }

    if (ErrorLog == null)
    {
        // no errors establishing the connection neither processing metadata
        return true;
    }
    else
        PublishErrorLog();
    return false;
}