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行为