1

假设一个Car模型对象(as 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的构建器的验证器提供,因为模型验证是最重要的验证位置,不应该依赖于其他任何东西。

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

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

4

1 回答 1

2

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

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

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

于 2013-02-18T00:35:48.463 回答