Exception 我的持久性类应该返回选项还是依赖异常?

Exception 我的持久性类应该返回选项还是依赖异常?,exception,scala,data-access-layer,Exception,Scala,Data Access Layer,我的应用程序的持久层由一个存储特性和一个实现类组成。我在这个问题上犹豫不决:fetchFoo(key:key)方法应该返回Option[Foo],还是在找不到键时抛出footfound异常 为了增加问题的趣味性,Java代码调用了持久层(用Scala编写)。在Java代码中处理scala.Option?嗯 事实上,直到昨天,持久层还是用Java编写的;我刚刚用Scala重新编写了它。作为Java代码库,它依赖于异常而不是返回null;但现在我遇到了scala.Option,我正在重新考虑。在我看

我的应用程序的持久层由一个存储特性和一个实现类组成。我在这个问题上犹豫不决:
fetchFoo(key:key)
方法应该返回
Option[Foo]
,还是在找不到键时抛出
footfound
异常

为了增加问题的趣味性,Java代码调用了持久层(用Scala编写)。在Java代码中处理scala.Option?嗯


事实上,直到昨天,持久层还是用Java编写的;我刚刚用Scala重新编写了它。作为Java代码库,它依赖于异常而不是返回null;但现在我遇到了scala.Option,我正在重新考虑。在我看来,Scala不像Java那样热衷于异常。

在Java中,您可以调用Option的
isEmpty
isDefined
get
,而无需任何特别的麻烦(真正有用的选项方法,如
getOrElse
,则是另一回事。)检查if子句中定义的
方法的结果应该比检查try-catch块中的异常更快。

我对一般问题的看法是,它取决于键的来源

如果它们是由某个用户或不受信任的系统输入的,那么我将使用
选项
,以便有意义地指出未知密钥的可能性,并对其进行适当处理

另一方面,如果密钥来自已知系统(这包括嵌入在最初来自系统的链接中的密钥),并且假定它们是有效的和存在的,那么我会将其作为运行时异常,由外部级别的catch all处理。例如,对于链接,如果有人出于某种原因手动更改url中的键,则应将其视为未定义的行为,并且应设置例外情况

另一种思考方式是,当情况发生时,你将如何处理。如果您正在使用
选项
并且只是将
None
案例委托给一些全面错误处理,那么异常可能更合适。如果显式捕获NotFound异常并更改程序流(例如,要求用户重新输入密钥),则使用
选项
,或选中异常(或Scala中的
),以确保情况得到处理

关于与Java的集成,
选项
在类路径上提供Scala运行时库之后就可以很容易地从那里使用了。或者,库中有一个
选项
实现。在任何情况下,我都不会使用
null
来表示“未找到”。

在某些情况下(如您的示例),选项很好,“一元”行为(map、flatMap、filter…)非常方便,但在其他情况下,您需要有关问题原因的更多信息,可以用异常更好地表示。现在,您可能希望错误处理尽可能“统一”,因此我建议使用,这将为您提供类似于选项的行为和类似异常的表现力

在Java中,您只需要一个helper函数,它可以“解压”一个helper函数。如果它找到一个右(值),它将返回该值,如果它找到一个左(异常),它将重新抛出该值。在此之后,您将恢复正常的Java行为