1

不変でビルダーパターンを使用して作成された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(Don't Repeat Yourself)は簡単に破れそうな予感がします。

実際、フォームの検証がもたらすものは何でも、Carモデルの検証は最も重要な検証場所であり、他のものに依存するべきではないため、これはビルダーのバリデーターによって既に提供されています。

ビルダーが使用するのと同じバリデーターオブジェクトを扱うHelperクラスに近いソリューションを想像します。Controllerただし、Web フォームの任意の検証ステップで個別に呼び出すために、すべての検証メソッドを取得publicする必要があります (上記のコード スニペットのように)。

DRY を破らないようにしながら、このビルダーの原則を維持するための良い方法は何でしょうか?

4

1 に答える 1

2

Formビルダー パターンを保持する場合は、インスタンスを作成しないでください。フォームは、入ってくる情報が正しいタイプであることを確認するだけです。Carフォームはフォームを作成するためのルールを知らないため、ファイナルを作成できませんCar。ビルダーは作成します。

したがって、フォームに中間オブジェクト (タプルまたはケース クラス) に何かを入れさせ、そのオブジェクトを使用して (ビルダーを使用してPossibleCar) ビルドするようにします。Car

利用可能な別のルートがありますが、それは、さまざまな種類の検証を適応させるための (おそらく複雑な) 構造を作成する必要があることを意味します。その後、ビルダーとフォームの両方がこれらの検証を (アダプターの助けを借りて) 使用して、有効な車を作成できます。私はあなたがどのルートを取るべきかアドバイスできるほど、あなたが置かれている状況について十分に知りません。

于 2013-02-18T00:35:48.463 に答える