我对编程很陌生,但我一直在努力确保学习良好的设计实践。我的问题与如何处理这种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;
}
答案 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;
}