验证Scala中的一个类凝聚力的方式我的目标是建立一个有效的User
实例之前验证小号apply
方法User
“的object
内S场”:使用Scalaz 7
case class User(String userName, String password)
object User {
def apply(userValidator: UserValidator): ValidationNel[UserCreationFailure, User] = {
//call UserValidator's validate() method here and initialize effective User instance.
}
}
我选择使用Validation
从Scalaz7积累潜在的非法论点/错误。
以下代码的一个缺点是Scalaz7 API迫使我使验证器自己创建实例。但是,通过遵循单责任原则,显然不是它的作用。它的作用是验证字段并返回一些错误列表。
让我们先来介绍我的实际代码(有关信息,Empty****
对象只是一些case object
延伸UserCreationFailure
):
class UserValidator(val userName: String, val password: String)
extends CommonValidator[UserCreationFailure] {
def validate(): ValidationNel[UserCreationFailure, User] = {
(checkForUserName ⊛
checkForPassword)((userName, password) => new User(userName, password)
}
private def checkForUserName: ValidationNel[UserCreationFailure, String] = {
checkForNonEmptyString(userName) {
EmptyUserName
}
}
def checkForPassword: ValidationNel[UserCreationFailure, String] = {
checkForNonEmptyString(password) {
EmptyPassword
}
}
}
我会想到的是仅仅返回此代码片段:
(checkForUserName ⊛ checkForPassword)
并将相应的结果带入我的User
类,从而可以通过执行以下操作创建有效实例:
def apply(userValidator: UserValidator): ValidationNel[UserCreationFailure, User] = {
userValidator(username, password).validate()((userName, password)(new User(userName, password))
}
事实上,它对SRP更友好。
但(checkForUserName ⊛ checkForPassword)
返回一个完全private
类型类型:
private[scalaz] trait ApplicativeBuilder[M[_], A, B]
,
因此,我没有手的class
类型返回。
因此,我不得不直接将用户的创建与它关联。
我该如何保持SRP并保持此验证机制?
----- UPDATE ----
由于@Travis布朗提到的,意图使用外部class
我UserValidator
可能看起来怪怪的。实际上,我希望验证器是可嘲弄的,因此,我不得不使用trait
/abstract class
的构图。
为什么我想处理组成而不是特质(继承)是因为我期望我的'UserValidator'是可嘲弄的。整个目标是提供一个'可嘲讽的'UserValidator',以便适合我的'User'类的单元测试。 – Mik378 2013-05-05 20:39:23
当然,我们不能嘲笑任何一个预定班的任何特质/超类。 – Mik378 2013-05-05 20:51:00
我喜欢你的解决方案,尽管我认为保持作文,因此与外部'UserValidator'类,但让'用户'类进行适当的不同验证方法调用,就像你已经提出的。非常感谢 :) – Mik378 2013-05-05 21:39:57