不変でビルダーパターンを使用して作成された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 を破らないようにしながら、このビルダーの原則を維持するための良い方法は何でしょうか?