处理对象字段验证的最佳方法=>要么/试试(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.
此构建器模式将包含一个 build
方法
This builder pattern would contain a build
method focusing on fields validation and then on conversion to the targeted type.
此验证可以使用以下方式实现:
This validation could be implemented using:
-
要么[FailureObject,TargetObject]
类型 -
Try [TargetObject]
(Scala 2.10的新功能) -
Validation [FailureObject,TargetObject]
或ValidationNEL [ scalaz库中的FailureObject,TargetObject]
Either[FailureObject, TargetObject]
typeTry[TargetObject]
(new feature from Scala 2.10)Validation[FailureObject, TargetObject]
orValidationNEL[FailureObject, TargetObject]
from scalaz library
我读到<$ c $的主要优势之一c>超过的验证
任一类型是 Validation
可以当场累积失败 。
I read that one of the main advantages of Validation
over Either
type is that Validation
can accumulate failures "out of the box".
但是新的 尝试
方式呢?我注意到 Try
也有 monadic方法,例如 map
, flatMap
等...在没有 Projection
的帮助下,任何一种类型实际上都缺少什么。
But what about the "new" Try
way? 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 [FieldType]
,更确切地说,如果出现任何失败,将返回 Try [ SpecificFieldExceptionType]
;这个嵌套的包含一个 String
消息字段和一个rootCause字段,该字段可以在整个 build
方法中累积。
Thus, I'd imagine each field validation method returning a Try[FieldType]
and more precisely, in case of any failure, a Try[SpecificFieldExceptionType]
; this nested one containing a String
message field and a rootCause field that could be accumulated throughout the build
method.
使用Scala 2.10,是否可以或应该尝试
练习替换scalaz验证库以进行简单的验证,例如涉及构建器模式?
Using Scala 2.10, could or should Try
practice replace scalaz validation library for simple validation like builder pattern involves?
**编辑 * ***
**EDIT ****
通过阅读 Try
源代码,听起来 Try
不能累积多个异常,因此面向快速失败。
即使 Try.flatMap
也会返回先前的潜在故障,因此没有累积的概念:
By reading Try
source code, it sounds that Try
can't accumulate several exceptions and thus is oriented fail-fast.
Even Try.flatMap
returns the potentential previous failure and so doesn't have the notion of accumulation:
def flatMap[U](f: T => Try[U]): Try[U] = this.asInstanceOf[Try[U]]
与处理累积功能的 ValidationNEL
相反。
On the contrary of ValidationNEL
that handles accumulation feature.
是否确认?
推荐答案
需要权衡:
-
scalaz.Validation
能够累积E
给出了Semigroup [E]
实例。它打算用作Applicative
,例如:
scalaz.Validation
is able to accumulate errors of typeE
given aSemigroup[E]
instance. It's intended for use as anApplicative
, like:
(fragileFoo |@| fragileBar) { case (foo, bar) => doSomething(foo, bar) }
它确实具有 map
和 flatMap
方法,偏向成功
端,因此您可以方便地在 for
-comprehension。但是,没有为其定义 Monad
实例,因此不能在任何高阶对象中使用它(例如,您不能将其与monad转换器一起使用)。
It does have map
and flatMap
methods, biased towards the Success
side, so you can use it conveniently in a for
-comprehension. 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). This shortcoming doesn't seem like it would be a problem for you, though.
scalaz.\ / $ c您未提及的$ c>确实形成了
Monad
(再次偏向右
端) 。但是,当用作适用性
时,它不会像 Validation
那样累积失败。
scalaz.\/
, which you didn't mention, does form a Monad
(again, biased toward the Right
side). But when used as an Applicative
, it doesn't accumulate failures as Validation
does.
util.Try
类似于 scalaz.\ /
,专门到 Throwable
。尽管它再次缺少错误累积,但确实具有错误恢复的概念。但是,对于您的构建器模式用例,这似乎并不是非常有用。
util.Try
is similar to scalaz.\/
, specialized to 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.
最后,是 util。
与其他三个选项相比不值得考虑:因为它不偏向一侧或另一侧,所以您必须明确而始终如一地要求左
或右
投影,每次您想进行单声道操作。
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.
我最好的猜测是,对于您的情况, scalaz.Validation
是最合适的选择。
My best guess is that for your situation, scalaz.Validation
is the most appropriate choice.
这篇关于处理对象字段验证的最佳方法=>要么/试试(scala 2.10)/ ValidationNEL(scalaz)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!