简体   繁体   English

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

[英]Best way to handle object's fields validation => Either / Try (scala 2.10) / ValidationNEL (scalaz)

Let's assume an object constructed using a builder pattern. 让我们假设一个使用构建器模式构造的对象。

This builder pattern would contain a build method focusing on fields validation and then on conversion to the targeted type. 此构建器模式将包含一个build方法,该方法侧重于字段验证,然后转换为目标类型。

This validation could be implemented using: 可以使用以下方式实现此验证:

  • Either[FailureObject, TargetObject] type Either[FailureObject, TargetObject]类型
  • Try[TargetObject] (new feature from Scala 2.10) Try[TargetObject] (Scala 2.10的新功能)
  • Validation[FailureObject, TargetObject] or ValidationNEL[FailureObject, TargetObject] from scalaz library 从scalaz库Validation[FailureObject, TargetObject]ValidationNEL[FailureObject, TargetObject]

I read that one of the main advantages of Validation over Either type is that Validation can accumulate failures "out of the box". 我读到Validation对于Either类型的主要优点之一是Validation可以“开箱即用”累积失败。

But what about the "new" Try way? 但是那个“新”的Try方式呢? I noticed that Try has "monadic" methods out of the box also, like map , flatMap etc... what was really missing with Either type without help of Projection . 我注意到Try也有开箱即用的“monadic”方法,比如mapflatMap等...在没有Projection帮助的情况下,任何一种类型都缺少什么。

Thus, I'd imagine each field validation method returning a Try[FieldType] and more precisely, in case of any failure, a Try[SpecificFieldExceptionType] ; 因此,我想每个字段验证方法返回一个Try[FieldType] ,更准确地说,如果发生任何故障,则返回Try[SpecificFieldExceptionType] ; this nested one containing a String message field and a rootCause field that could be accumulated throughout the build method. 这个嵌套的包含String消息字段和rootCause字段,可以在整个build方法中累积。

Using Scala 2.10, could or should Try practice replace scalaz validation library for simple validation like builder pattern involves? 使用Scala 2.10,可以或应该Try练习替换scalaz验证库以进行简单验证,如构建器模式涉及?

**EDIT * *** **编辑* ***

By reading Try source code, it sounds that Try can't accumulate several exceptions and thus is oriented fail-fast. 通过阅读Try源代码,听起来Try不能累积多个异常,因此面向失败快速。 Even Try.flatMap returns the potentential previous failure and so doesn't have the notion of accumulation: 即使Try.flatMap返回可能的先前失败,因此没有累积的概念:

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

On the contrary of ValidationNEL that handles accumulation feature. 相反, ValidationNEL处理累积功能。

Any confirmation? 任何确认?

There are tradeoffs: 有权衡:

  • scalaz.Validation is able to accumulate errors of type E given a Semigroup[E] instance. scalaz.Validation能够在给定scalaz.Validation Semigroup[E]实例的情况下累积E类型的错误。 It's intended for use as an Applicative , like: 它旨在用作Applicative ,例如:

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

    It does have map and flatMap methods, biased towards the Success side, so you can use it conveniently in a for -comprehension. 它确实有mapflatMap方法,偏向于Success方面,所以你可以方便地使用它for理解。 However, there is no Monad instance defined for it, so it can't be used in any higher-order stuff (for example, you can't use it with monad transformers). 但是,没有为它定义Monad实例,因此它不能用于任何更高阶的东西(例如,你不能将它用于monad变换器)。 This shortcoming doesn't seem like it would be a problem for you, though. 不过,这个缺点对你来说似乎不是一个问题。

  • scalaz.\\/ , which you didn't mention, does form a Monad (again, biased toward the Right side). scalaz.\\/ ,你没有提到,确实形成了一个Monad (再次偏向Right )。 But when used as an Applicative , it doesn't accumulate failures as Validation does. 但是当用作Applicative ,它不会像Validation那样累积失败。

  • util.Try is similar to scalaz.\\/ , specialized to Throwable . util.Try类似于scalaz.\\/ ,专门用于Throwable Although it again lacks accumulation of errors, it does have the notion of error recovery. 虽然它再次缺乏错误累积,但它确实具有错误恢复的概念。 However, for your "builder pattern" use case, it seems like this might not be terribly useful. 但是,对于“构建器模式”用例,似乎这可能不是非常有用。

  • Finally, util.Either isn't worth considering, compared to the other three options: because it's not biased toward one side or the other, you have to explicitly and consistently ask for the left or right projection every time you want to do something monadic. 最后, util.Either是不值得考虑,相对于其他三个选项:因为它不是朝着一侧或另一偏置,你必须明确和一贯要求的leftright ,你想做些什么,每次一元投影。

My best guess is that for your situation, scalaz.Validation is the most appropriate choice. 我最好的猜测是,对于你的情况, scalaz.Validation是最合适的选择。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM