【问题标题】:Play Framework 2 / Redundant object validationsPlay Framework 2 / 冗余对象验证
【发布时间】:2013-02-02 08:53:03
【问题描述】:

假设有一个Car 模型对象(如case class),它是不可变的并使用构建器模式创建。 (Joshua Bloch 的建造者模式)。

它的build 方法调用CarValidator 对象以允许创建或不创建相关Car。否则,它会抛出一个IllegalStateException,其中会精确处理意外字段。

因此,没有人可以在运行时随时创建陈旧或无效的Car,太棒了!

假设现在有一个 Web 表单来创建 Car。 Play 的控制器将包含此表单映射:

val carForm = Form(               //this is a conceptual sample
    mapping(
      "brand" -> nonEmptyText,
      "description" -> nonEmptyText,
      "maxSpeed" -> number
      "complexElement" -> number.verifying(........) //redundant validation here
    )(Car.apply)(Car.unapply)
  )   

在此示例中,有一些基本字段,但想象更复杂的字段需要复杂的业务验证,例如此处的 complexeElement。

我真的觉得我很容易打破DRY(不要重复自己)。

确实,无论表单验证会带来什么,这将由我的Car builder 的验证器提供,因为模型验证是最重要的验证位置,不应依赖于其他任何东西。

我想象一个解决方案,在我的 Controller 附近有一个 Helper 类来处理我的构建器使用的相同验证器对象。但是,它迫使我获取所有验证方法public,以便在我的 Web 表单的任何验证步骤中独立调用(如上面的代码 sn-p)。

在避免破坏 DRY 的同时保持此构建器原则的良好做法是什么?

【问题讨论】:

    标签: java scala validation playframework-2.0


    【解决方案1】:

    如果您想保留构建器模式,您不应该让Form 创建实例。该表格应确保输入的信息类型正确。表单无法创建最终的Car,因为它不知道创建Car 的规则,而构建器知道。

    所以我想说你让表单将东西放入一个中间对象(元组或PossibleCar 案例类)并使用该对象构建你的Car(使用构建器)。

    还有另一种可用的方法,但这意味着您必须创建(可能很复杂)结构,以便适应不同类型的验证。然后,构建器和表单都可以使用这些验证(在适配器的帮助下)来创建有效的汽车。我对您所处的情况了解得不够多,无法就采取哪条路线向您提供建议。

    【讨论】:

    • 如果我不直接在映射中显式验证,如何使用 Play 提供的错误通知机制而映射表单?
    • 可以使用Form类的withError方法
    • 最后,我选择在我的模型和表单之间共享一个验证器。这个验证器返回一些ValidationNEL(来自scalaz),我必须将它们调整为Constraint,以便将它们设置为我的表单的verifyingmethod。第一个建议的解决方案不是最佳的,因为有了它,我们永远无法一步完成整个错误列表。
    • 听起来是个不错的解决方案。您愿意分享一些代码(或示例)吗? GitHub Gist 可能是个好地方。
    • 我完成了一些任务,并尝试提出一个好的要点
    猜你喜欢
    • 1970-01-01
    • 2015-02-20
    • 1970-01-01
    • 2013-12-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-01-28
    相关资源
    最近更新 更多