我正在开发一个安卓服务,并遇到了两种不同的风格来编写代码来处理验证。
第一种样式:使用布尔或显式检查。在此方法中,我返回从函数中获得的任何值。返回的值可以为空、已关闭(无效)。
boolean fbConnected = appPrefences.isFBConnected();
if (!fbConnected)
{
ShowNotification("FB not connected");
stopSelf();
return;
}
Session session = GetSession();
if (session.isClosed())
{
ShowNotification("Session not valid");
stopSelf();
return;
}
Coordinates result = getLocation();
if(result == null)
{
ShowNotification("Could not get location");
stopSelf();
return;
}
// Do something finally with Session, FB and location
第二种样式:使用异常处理。在这里,如果会话关闭(无效)或位置为 null,我将从实用程序方法中抛出自己的自定义异常。我按如下方式处理它:
try
{
appPrefences.connectToFb();
Session session = GetSession();
Coordinates result = getLocation();
}
catch(FBException e)
{
ShowNotification("FB not connected");
stopSelf();
return;
}
catch(SessionException e)
{
ShowNotification("Session not valid");
stopSelf();
return;
}
catch(LocationException e)
{
ShowNotification("Could not get location");
stopSelf();
return;
}
// Do something finally with Session, FB and location
在我看来,第一个更好,原因如下:
- 在第二种方法中,引发异常会导致性能下降。
第一种方法可以吗,或者使用第二种方法有一些真正的好处?
使用异常
-
表示调用方违反了调用函数的前提条件。这通常会导致程序中的修复,因为调用方有责任确保满足先决条件。
-
表示函数无法确保后置条件,尽管满足了调用函数的前提条件。这应由调用方正常处理。
我认为像isFBConnected
这样的功能应该检查Facebook是否已连接。有两个完全有效的答案:是,不是。如果函数无法确定 facebook 是否已连接,则应引发异常。
在正常程序流中使用 try/catch 块会导致性能下降。 最好在第一个示例中使用 if/then 语句。
https://softwareengineering.stackexchange.com/questions/189222/are-exceptions-as-control-flow-considered-a-serious-antipattern-if-so-why
这在Effective Java中提到过。 顾名思义,例外情况仅用于特殊情况;它们绝不应用于普通控制流。
同意劳尔的回答。我想补充一点,当您开发可供其他(如库或 sdk)使用的代码时,异常很有用。显式异常提供了有用的反馈,并且可以节省大量调试时间,尤其是在它们无法访问源代码的情况下。
例如,如果您在Android中开发了一个特殊的Layout
,需要排除儿童视图才能工作,那么您可以抛出一个异常,说"正好需要两个孩子",这样用户就不会陷入crypric崩溃并知道该怎么做。
在我看来,第一种方法是可以的,因为除了捕获它之外,您实际上没有做任何事情 异常方面
生成、抛出和捕获异常会产生性能开销。当然,在可能经常执行的低级代码中,您不希望为标准操作生成和捕获大量不必要的异常。