处理对象的最佳方式';s字段验证=>;或者/Try(scala 2.10)/ValidationNEL(scalaz)

处理对象的最佳方式';s字段验证=>;或者/Try(scala 2.10)/ValidationNEL(scalaz),scala,exception-handling,builder-pattern,scalaz7,Scala,Exception Handling,Builder Pattern,Scalaz7,让我们假设一个使用构建器模式构建的对象 此生成器模式将包含一个build方法,该方法侧重于字段验证,然后转换为目标类型 此验证可通过以下方式实施: 任一[FailureObject,TargetObject]类型 试试[TargetObject](Scala 2.10的新功能) Validation[FailureObject,TargetObject]或ValidationNEL[FailureObject,TargetObject]来自scalaz库 我读到,验证比或类型的主要优点之一是

让我们假设一个使用构建器模式构建的对象

此生成器模式将包含一个
build
方法,该方法侧重于字段验证,然后转换为目标类型

此验证可通过以下方式实施:

  • 任一[FailureObject,TargetObject]
    类型
  • 试试[TargetObject]
    (Scala 2.10的新功能)
  • Validation[FailureObject,TargetObject]
    ValidationNEL[FailureObject,TargetObject]
    来自scalaz库
我读到,
验证
类型的主要优点之一是
验证
可以“开箱即用”地累积失败

但是“新”的
尝试方法呢?我注意到,
Try
也有现成的“一元”方法,如
map
flatMap
等。。。没有
投影的帮助,两种类型都缺少什么

因此,我设想每个字段验证方法都返回一个
Try[FieldType]
,更准确地说,如果出现任何故障,则返回一个
Try[SpecificFieldExceptionType]
;这个嵌套字段包含一个
字符串
消息字段和一个可在整个
构建
方法中累积的根本原因字段

使用Scala2.10,
Try
practice可以或应该代替scalaz验证库进行简单的验证,比如构建器模式

**编辑****

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

def flatMap[U](f: T => Try[U]): Try[U] = this.asInstanceOf[Try[U]]
与处理累积功能的
ValidationNEL
相反

有确认吗?

需要权衡:

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

    (fragileFoo |@| fragileBar) { case (foo, bar) => doSomething(foo, bar) }
    
    它确实有
    map
    flatMap
    方法,偏向于
    Success
    方面,因此您可以方便地在
    中使用它进行理解。但是,没有为它定义的
    Monad
    实例,因此它不能用于任何高阶内容(例如,不能与Monad transformers一起使用)。不过,这个缺点对你来说似乎不是问题

  • scalaz.\/
    ,您没有提到,它确实形成了一个
    Monad
    (同样,偏向
    右侧)。但当用作
    应用程序时
    ,它不会像
    验证
    那样累积失败

  • util.Try
    类似于
    scalaz.\/
    ,专门用于
    Throwable
    。尽管它同样缺乏错误的积累,但它确实有错误恢复的概念。然而,对于您的“构建器模式”用例来说,这似乎不是非常有用

  • 最后,
    util。与其他三个选项相比,要么
    不值得考虑:因为它不偏向一边或另一边,所以每次你想做一元的事情时,你都必须明确且一致地要求
    投影


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

无法想象更好的答案=>解释得很好!非常感谢:)事实上,我选择了验证来与我的构建器一起工作。