[英]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”方法,比如map
, flatMap
等...在没有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. 它确实有map
和flatMap
方法,偏向于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
是不值得考虑,相对于其他三个选项:因为它不是朝着一侧或另一偏置,你必须明确和一贯要求的left
或right
,你想做些什么,每次一元投影。
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.