假设使用构建器模式构造对象。
此构建器模式将包含build
方法,侧重于字段验证,然后转换为目标类型。
此验证可以使用以下方式实施:
Either[FailureObject, TargetObject]
类型Try[TargetObject]
(Scala 2.10的新功能)Validation[FailureObject, TargetObject]
或ValidationNEL[FailureObject, TargetObject]
我读到Validation
超过Either
类型的一个主要优点是Validation
可以“开箱即用”累积失败。
但是“新”Try
方式怎么样?我注意到Try
开箱即用的是“monadic”方法,例如map
,flatMap
等等...在没有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
相反。
有任何确认吗?
答案 0 :(得分:11)
有权衡:
scalaz.Validation
能够在给定E
实例的情况下累积Semigroup[E]
类型的错误。它旨在用作Applicative
,例如:
(fragileFoo |@| fragileBar) { case (foo, bar) => doSomething(foo, bar) }
它确实有map
和flatMap
方法,偏向Success
方面,因此您可以在for
- 理解中方便地使用它。但是,没有为它定义Monad
实例,因此它不能用于任何更高阶的东西(例如,你不能将它与monad变换器一起使用)。不过,这个缺点对你来说似乎不是一个问题。
scalaz.\/
确实形成Monad
(再次偏向Right
方)。但是,当用作Applicative
时,它不会像Validation
那样累积失败。
util.Try
与scalaz.\/
相似,专门针对Throwable
。虽然它再次缺乏错误累积,但它确实具有错误恢复的概念。但是,对于“构建器模式”用例,似乎这可能不是非常有用。
最后,与其他三个选项相比,util.Either
不值得考虑:因为它不偏向一方或另一方,所以你必须明确且一致地要求{{1}每当你想做一些monadic时,或left
投射。
我最好的猜测是,对于您的情况,right
是最合适的选择。