处理对象字段验证的最佳方法=>要么/尝试(scala 2.10)/ ValidationNEL(scalaz)

时间:2013-02-27 18:45:11

标签: scala exception-handling builder-pattern scalaz7

假设使用构建器模式构造对象。

此构建器模式将包含build方法,侧重于字段验证,然后转换为目标类型。

此验证可以使用以下方式实施:

  • Either[FailureObject, TargetObject]类型
  • Try[TargetObject](Scala 2.10的新功能)
  • 来自scalaz library的
  • Validation[FailureObject, TargetObject]ValidationNEL[FailureObject, TargetObject]

我读到Validation超过Either类型的一个主要优点是Validation可以“开箱即用”累积失败。

但是“新”Try方式怎么样?我注意到Try开箱即用的是“monadic”方法,例如mapflatMap等等...在没有Projection帮助的情况下,任何类型都缺少什么

因此,我想象每个字段验证方法返回Try[FieldType],更确切地说,如果发生任何失败,则返回Try[SpecificFieldExceptionType];这个嵌套的包含String消息字段和rootCause字段,可以在build方法中累积。

使用Scala 2.10,可以或应该Try练习替换scalaz验证库以进行简单验证,例如构建器模式涉及吗?

**编辑 * ***

通过阅读Try源代码,听起来Try无法累积多个异常,因此面向失败快速。 即使Try.flatMap返回可能的先前失败,因此没有积累的概念:

def flatMap[U](f: T => Try[U]): Try[U] = this.asInstanceOf[Try[U]]

与处理累积功能的ValidationNEL相反。

有任何确认吗?

1 个答案:

答案 0 :(得分:11)

有权衡:

  • scalaz.Validation能够在给定E实例的情况下累积Semigroup[E]类型的错误。它旨在用作Applicative,例如:

    (fragileFoo |@| fragileBar) { case (foo, bar) => doSomething(foo, bar) }
    

    它确实有mapflatMap方法,偏向Success方面,因此您可以在for - 理解中方便地使用它。但是,没有为它定义Monad实例,因此它不能用于任何更高阶的东西(例如,你不能将它与monad变换器一起使用)。不过,这个缺点对你来说似乎不是一个问题。

  • 您未提及的
  • scalaz.\/确实形成Monad(再次偏向Right方)。但是,当用作Applicative时,它不会像Validation那样累积失败。

  • util.Tryscalaz.\/相似,专门针对Throwable。虽然它再次缺乏错误累积,但它确实具有错误恢复的概念。但是,对于“构建器模式”用例,似乎这可能不是非常有用。

  • 最后,与其他三个选项相比,util.Either不值得考虑:因为它不偏向一方或另一方,所以你必须明确且一致地要求{{1}每当你想做一些monadic时,或left投射。

我最好的猜测是,对于您的情况,right是最合适的选择。